mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 08:38:38 +08:00
An address environment is the property of a task group, not of a thread
This commit is contained in:
parent
150fcfb5b8
commit
1d586e6136
13 changed files with 278 additions and 306 deletions
|
@ -8,7 +8,7 @@
|
|||
<tr align="center" bgcolor="#e4e4e4">
|
||||
<td>
|
||||
<h1><big><font color="#3c34ec"><i>NuttX Binary Loader</i></font></big></h1>
|
||||
<p>Last Updated: January 16, 2013</p>
|
||||
<p>Last Updated: August 22, 2014</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -170,7 +170,7 @@ struct binary_s
|
|||
*/
|
||||
|
||||
#ifdef CONFIG_ADDRENV
|
||||
task_addrenv_t addrenv; /* Task address environment */
|
||||
group_addrenv_t addrenv; /* Task group address environment */
|
||||
#endif
|
||||
|
||||
size_t mapsize; /* Size of the mapped address region (needed for munmap) */
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<h1><big><font color="#3c34ec">
|
||||
<i>NuttX RTOS Porting Guide</i>
|
||||
</font></big></h1>
|
||||
<p>Last Updated: August 21, 2014</p>
|
||||
<p>Last Updated: August 22, 2014</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -107,13 +107,13 @@
|
|||
<a href="#addrenv">4.4 Address Environments</a>
|
||||
<ul>
|
||||
<a href="#up_addrenv_create">4.4.1 <code>up_addrenv_create()</code></a></br>
|
||||
<a href="#up_addrenv_vaddr">4.4.2 <code>up_addrenv_vaddr()</code></a></br>
|
||||
<a href="#up_addrenv_select">4.4.3 <code>up_addrenv_select()</code></a></br>
|
||||
<a href="#up_addrenv_restore">4.4.4 <code>up_addrenv_restore()</code></a></br>
|
||||
<a href="#up_addrenv_destroy">4.4.5 <code>up_addrenv_destroy()</code></a></br>
|
||||
<a href="#up_addrenv_destroy">4.4.2 <code>up_addrenv_destroy()</code></a></br>
|
||||
<a href="#up_addrenv_vaddr">4.4.3 <code>up_addrenv_vaddr()</code></a></br>
|
||||
<a href="#up_addrenv_select">4.4.4 <code>up_addrenv_select()</code></a></br>
|
||||
<a href="#up_addrenv_restore">4.4.5 <code>up_addrenv_restore()</code></a></br>
|
||||
<a href="#up_addrenv_assign">4.4.6 <code>up_addrenv_assign()</code></a></br>
|
||||
<a href="#up_addrenv_share">4.4.7 <code>up_addrenv_share()</code></a></br>
|
||||
<a href="#up_addrenv_release">4.4.8 <code>up_addrenv_release()</code></a>
|
||||
<a href="#up_addrenv_attach">4.4.7 <code>up_addrenv_attach()</code></a></br>
|
||||
<a href="#up_addrenv_detach">4.4.8 <code>up_addrenv_detach()</code></a>
|
||||
</ul>
|
||||
<a href="#exports">4.5 APIs Exported by NuttX to Architecture-Specific Logic</a>
|
||||
<ul>
|
||||
|
@ -2625,7 +2625,7 @@ int up_alarm_cancel(FAR struct timespec *ts);
|
|||
May be called from interrupt level handling or from the normal tasking level. iterrupts may need to be disabled internally to assure non-reentrancy.
|
||||
</ul>
|
||||
|
||||
<h5><a name="upalarmstart">4.3.4.4.5 <code>up_alarm_start()</code></a></h5>
|
||||
<h5><a name="upalarmstart">4.3.4.4.4 <code>up_alarm_start()</code></a></h5>
|
||||
<p><b>Function Prototype</b>:<p>
|
||||
<ul><pre>
|
||||
#include <nuttx/arch.h>
|
||||
|
@ -2930,8 +2930,7 @@ VxWorks provides the following comparable interface:
|
|||
<p>
|
||||
<b>Binary Loader Support</b>.
|
||||
These are low-level interfaces used in <code>binfmt/</code> to instantiate tasks with address environments.
|
||||
These interfaces all operate on type <code>task_addrenv_t</code> which is an abstract representation of a asks's address environment and must be defined in arch/arch.h if <code>CONFIG_ADDRENV</code> is defined.
|
||||
These low-level interfaces include:
|
||||
These interfaces all operate on type <code>group_addrenv_t</code> which is an abstract representation of a task group's address environment and the type must be defined in<code>arch/arch.h</code> if <code>CONFIG_ADDRENV</code> is defined. These low-level interfaces include:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
|
@ -2939,24 +2938,24 @@ VxWorks provides the following comparable interface:
|
|||
Create an address environment.
|
||||
</li>
|
||||
<li>
|
||||
<a href="#up_addrenv_vaddr">4.4.2 <code>up_addrenv_vaddr()</code></a>:
|
||||
Returns the virtual base address of the address environment.
|
||||
</li>
|
||||
<li>
|
||||
<a href="#up_addrenv_select">4.4.3 <code>up_addrenv_select()</code></a>:
|
||||
Instantiate an address environment.
|
||||
</li>
|
||||
<li>
|
||||
<a href="#up_addrenv_restore">4.4.4 <code>up_addrenv_restore()</code></a>:
|
||||
Restore an address environment.
|
||||
</li>
|
||||
<li>
|
||||
<a href="#up_addrenv_destroy">4.4.5 <code>up_addrenv_destroy()</code></a>:
|
||||
<a href="#up_addrenv_destroy">4.4.2 <code>up_addrenv_destroy()</code></a>:
|
||||
Destroy an address environment.
|
||||
</li>
|
||||
<li>
|
||||
<a href="#up_addrenv_vaddr">4.4.3 <code>up_addrenv_vaddr()</code></a>:
|
||||
Returns the virtual base address of the address environment.
|
||||
</li>
|
||||
<li>
|
||||
<a href="#up_addrenv_select">4.4.4 <code>up_addrenv_select()</code></a>:
|
||||
Instantiate an address environment.
|
||||
</li>
|
||||
<li>
|
||||
<a href="#up_addrenv_restore">4.4.5 <code>up_addrenv_restore()</code></a>:
|
||||
Restore an address environment.
|
||||
</li>
|
||||
<li>
|
||||
<a href="#up_addrenv_assign">4.4.6 <code>up_addrenv_assign()</code></a>:
|
||||
Assign an address environment to a TCB.
|
||||
Assign an address environment to a thread.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
@ -2964,31 +2963,30 @@ VxWorks provides the following comparable interface:
|
|||
<p>
|
||||
<b>Tasking Support</b>.
|
||||
Other interfaces must be provided to support higher-level interfaces used by the NuttX tasking logic.
|
||||
These interfaces are* used by the functions in <code>sched/</code> and all operate on the TCB which as been assigned an address environment by <code>up_addrenv_assign()</code>.
|
||||
These interfaces are* used by the functions in <code>sched/</code> and all operate on the task group which as been assigned an address environment by <code>up_addrenv_assign()</code>.
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#up_addrenv_share">4.4.7 <code>up_addrenv_share()</code></a>:
|
||||
Clone the address environment assigned to one TCB to another.
|
||||
<a href="#up_addrenv_attach">4.4.7 <code>up_addrenv_attach()</code></a>:
|
||||
Clone the group address environment assigned to a new thread.
|
||||
This operation is done when a pthread is created that share's the same address environment.
|
||||
</li>
|
||||
<li>
|
||||
<a href="#up_addrenv_release">4.4.8 <code>up_addrenv_release()</code></a>:
|
||||
Release the TCB's reference to an address environment when a task/thread exits.
|
||||
<a href="#up_addrenv_detach">4.4.8 <code>up_addrenv_detach()</code></a>:
|
||||
Release the thread's reference to a group address environment when a task/thread exits.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
|
||||
<h3><a name="up_addrenv_create">4.4.1 <code>up_addrenv_create()</code></a></h3>
|
||||
<p><b>Function Prototype</b>:</p>
|
||||
<ul>
|
||||
<code>int up_addrenv_create(size_t envsize, FAR task_addrenv_t *addrenv);</code>
|
||||
<code>int up_addrenv_create(size_t envsize, FAR group_addrenv_t *addrenv);</code>
|
||||
</ul>
|
||||
<p><b>Description</b>:</p>
|
||||
<ul>
|
||||
This function is called from the binary loader logic when a new task is created in order to instantiate an address environment for the task.
|
||||
This function is called when a new task is created in order to instantiate an address environment for the new task group.
|
||||
<code>up_addrenv_create()</code> is essentially the allocator of the physical memory for the new task.
|
||||
</ul>
|
||||
<p><b>Input Parameters</b>:</p>
|
||||
|
@ -3001,10 +2999,28 @@ VxWorks provides the following comparable interface:
|
|||
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
|
||||
</ul>
|
||||
|
||||
<h3><a name="up_addrenv_vaddr">4.4.2 <code>up_addrenv_vaddr()</code></a></h3>
|
||||
<h3><a name="up_addrenv_destroy">4.4.2 <code>up_addrenv_destroy()</code></a></h3>
|
||||
<p><b>Function Prototype</b>:<p>
|
||||
<ul>
|
||||
<code>int up_addrenv_vaddr(FAR task_addrenv_t addrenv, FAR void **vaddr);</code>
|
||||
<code>int up_addrenv_destroy(group_addrenv_t addrenv);</code>
|
||||
</ul>
|
||||
<p><b>Description</b>:</p>
|
||||
<ul>
|
||||
This function is called when a final thread leaves the task group and the task group is destroyed. This function then destroys the defunct address environment, releasing the underlying physical memory allocated by <code>up_addrenv_create()</code>.
|
||||
</ul>
|
||||
<p><b>Input Parameters</b>:</p>
|
||||
<ul>
|
||||
<li><code>addrenv</code>: The representation of the task address environment previously returned by up_addrenv_create.</li>
|
||||
</ul>
|
||||
<p><b>Returned Value</b>:</p>
|
||||
<ul>
|
||||
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
|
||||
</ul>
|
||||
|
||||
<h3><a name="up_addrenv_vaddr">4.4.3 <code>up_addrenv_vaddr()</code></a></h3>
|
||||
<p><b>Function Prototype</b>:<p>
|
||||
<ul>
|
||||
<code>int up_addrenv_vaddr(FAR group_addrenv_t addrenv, FAR void **vaddr);</code>
|
||||
</ul>
|
||||
<p><b>Description</b>:</p>
|
||||
<ul>
|
||||
|
@ -3021,10 +3037,10 @@ VxWorks provides the following comparable interface:
|
|||
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
|
||||
</ul>
|
||||
|
||||
<h3><a name="up_addrenv_select">4.4.3 <code>up_addrenv_select()</code></a></h3>
|
||||
<h3><a name="up_addrenv_select">4.4.4 <code>up_addrenv_select()</code></a></h3>
|
||||
<p><b>Function Prototype</b>:<p>
|
||||
<ul>
|
||||
<code>int up_addrenv_select(task_addrenv_t addrenv, hw_addrenv_t *oldenv);</code>
|
||||
<code>int up_addrenv_select(group_addrenv_t addrenv, hw_addrenv_t *oldenv);</code>
|
||||
</ul>
|
||||
<p><b>Description</b>:</p>
|
||||
<ul>
|
||||
|
@ -3037,7 +3053,7 @@ VxWorks provides the following comparable interface:
|
|||
<li><code>oldenv</code>:
|
||||
The address environment that was in place before <code>up_addrenv_select()</code> was called.
|
||||
This may be used with <code>up_addrenv_restore()</code> to restore the original address environment that was in place before <code>up_addrenv_select()</code> was called.
|
||||
Note that this may be a task agnostic, hardware representation that is different from <code>task_addrenv_t</code>.
|
||||
Note that this may be a task agnostic, hardware representation that is different from <code>group_addrenv_t</code>.
|
||||
</li>
|
||||
</ul>
|
||||
<p><b>Returned Value</b>:</p>
|
||||
|
@ -3045,7 +3061,7 @@ VxWorks provides the following comparable interface:
|
|||
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
|
||||
</ul>
|
||||
|
||||
<h3><a name="up_addrenv_restore">4.4.4 <code>up_addrenv_restore()</code></a></h3>
|
||||
<h3><a name="up_addrenv_restore">4.4.5 <code>up_addrenv_restore()</code></a></h3>
|
||||
<p><b>Function Prototype</b>:<p>
|
||||
<ul>
|
||||
<code>int up_addrenv_restore(hw_addrenv_t oldenv);</code>
|
||||
|
@ -3064,76 +3080,63 @@ VxWorks provides the following comparable interface:
|
|||
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
|
||||
</ul>
|
||||
|
||||
<h3><a name="up_addrenv_destroy">4.4.5 <code>up_addrenv_destroy()</code></a></h3>
|
||||
<p><b>Function Prototype</b>:<p>
|
||||
<ul>
|
||||
<code>int up_addrenv_destroy(task_addrenv_t addrenv);</code>
|
||||
</ul>
|
||||
<p><b>Description</b>:</p>
|
||||
<ul>
|
||||
Called from the binary loader loader during error handling to destroy the address environment previously created by <code>up_addrenv_create()</code>.
|
||||
</ul>
|
||||
<p><b>Input Parameters</b>:</p>
|
||||
<ul>
|
||||
<li><code>addrenv</code>: The representation of the task address environment previously returned by up_addrenv_create.</li>
|
||||
</ul>
|
||||
<p><b>Returned Value</b>:</p>
|
||||
<ul>
|
||||
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
|
||||
</ul>
|
||||
|
||||
<h3><a name="up_addrenv_assign">4.4.6 <code>up_addrenv_assign()</code></a></h3>
|
||||
<p><b>Function Prototype</b>:<p>
|
||||
<ul>
|
||||
<code>int up_addrenv_assign(task_addrenv_t addrenv, FAR struct tcb_s *tcb);</code>
|
||||
<code>int up_addrenv_assign(group_addrenv_t addrenv, FAR struct task_group_s *group);</code>
|
||||
</ul>
|
||||
<p><b>Description</b>:</p>
|
||||
<ul>
|
||||
Assign an address environment to a TCB.
|
||||
Assign an address environment to a new task group.
|
||||
</ul>
|
||||
<p><b>Input Parameters</b>:</p>
|
||||
<ul>
|
||||
<li><code>addrenv</code>: The representation of the task address environment previously returned by up_addrenv_create.</li>
|
||||
<li><code>tcb</code>: The TCB of the task to receive the address environment.</li>
|
||||
<li><code>addrenv</code>: The representation of the group address environment previously returned by <code>up_addrenv_create</code>.</li>
|
||||
<li><code>group</code>: The new task group to receive the address environment.</li>
|
||||
</ul>
|
||||
<p><b>Returned Value</b>:</p>
|
||||
<ul>
|
||||
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
|
||||
</ul>
|
||||
|
||||
<h3><a name="up_addrenv_share">4.4.7 <code>up_addrenv_share()</code></a></h3>
|
||||
<h3><a name="up_addrenv_attach">4.4.7 <code>up_addrenv_attach()</code></a></h3>
|
||||
<p><b>Function Prototype</b>:<p>
|
||||
<ul>
|
||||
<code>int up_addrenv_share(FAR const struct tcb_s *ptcb, FAR struct tcb_s *ctcb);</code>
|
||||
<code>int up_addrenv_attach(FAR struct task_group_s *group, FAR struct tcb_s *tcb);</code>
|
||||
</ul>
|
||||
<p><b>Description</b>:</p>
|
||||
<ul>
|
||||
This function is called from the core scheduler logic when a thread is created that needs to share the address environment of its parent task.
|
||||
In this case, the parent's address environment needs to be "cloned" for the child thread.
|
||||
<p>
|
||||
This function is called from the core scheduler logic when a thread is created that needs to share the address environment of its task group.
|
||||
In this case, the group's address environment may need to be "cloned" for the child thread.
|
||||
</p>
|
||||
<p>
|
||||
NOTE: In most platforms, nothing will need to be done in this case.
|
||||
Simply being a member of the group that has the address environment may be sufficient.
|
||||
</p>
|
||||
</ul>
|
||||
<p><b>Input Parameters</b>:</p>
|
||||
<ul>
|
||||
<li><code>ptcb</code>: The TCB of the parent task that has the address environment.</li>
|
||||
<li><code>ctcb</code>: The TCB of the child thread needing the address environment.</li>
|
||||
<li><code>group</code>: The task group to which the new thread belongs.</li>
|
||||
<li><code>ctcb</code>: The TCB of the thread needing the address environment.</li>
|
||||
</ul>
|
||||
<p><b>Returned Value</b>:</p>
|
||||
<ul>
|
||||
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
|
||||
</ul>
|
||||
|
||||
<h3><a name="up_addrenv_release">4.4.8 <code>up_addrenv_release()</code></a></h3>
|
||||
<h3><a name="up_addrenv_detach">4.4.8 <code>up_addrenv_detach()</code></a></h3>
|
||||
<p><b>Function Prototype</b>:<p>
|
||||
<ul>
|
||||
<code>int up_addrenv_release(FAR struct tcb_s *tcb);</code>
|
||||
<code>int up_addrenv_detach(FAR struct task_group_s *group, FAR struct task_group_s *tcb);</code>
|
||||
</ul>
|
||||
<p><b>Description</b>:</p>
|
||||
<ul>
|
||||
This function is called when a task or thread exits in order to release its reference to an address environment.
|
||||
When there are no further references to an address environment, that address environment should
|
||||
be destroyed.
|
||||
This function is called when a task or thread exits in order to release its reference to an address environment. The address environment, however, should persist until up_addrenv_destroy() is called when the task group is itself destroyed. Any resources unique to this thread may be destroyed now.
|
||||
</ul>
|
||||
<p><b>Input Parameters</b>:</p>
|
||||
<ul>
|
||||
<li><code>group</code>: The group to which the thread belonged.</li>
|
||||
<li><code>tcb</code>: The TCB of the task or thread whose the address environment will be released.</li>
|
||||
</ul>
|
||||
<p><b>Returned Value</b>:</p>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/****************************************************************************
|
||||
* arch/z80/arch.h
|
||||
* arch/chip/arch.h
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
|
@ -73,7 +72,7 @@ typedef uint8_t hw_addrenv_t;
|
|||
*/
|
||||
|
||||
struct z180_cbr_s;
|
||||
typedef FAR struct z180_cbr_s *task_addrenv_t;
|
||||
typedef FAR struct z180_cbr_s *group_addrenv_t;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -173,7 +173,7 @@ typedef uint16_t chipreg_t;
|
|||
struct z180_cbr_s
|
||||
{
|
||||
uint8_t cbr; /* The CBR value used by the thread */
|
||||
uint8_t crefs; /* The number of threads sharing this CBR value */
|
||||
uint8_t crefs; /* The number of task groups using this CBR value (0 or 1) */
|
||||
uint8_t pages; /* The number of 4KB pages of physical memory in the allocation */
|
||||
};
|
||||
|
||||
|
@ -183,10 +183,6 @@ struct z180_cbr_s
|
|||
|
||||
struct xcptcontext
|
||||
{
|
||||
/* CBR allocation */
|
||||
|
||||
FAR struct z180_cbr_s *cbr;
|
||||
|
||||
/* Register save area */
|
||||
|
||||
chipreg_t regs[XCPTCONTEXT_REGS];
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* arch/z80/src/z180/z180_mmu.c
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2012, 2014 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -180,36 +180,37 @@ return g_physhandle ? OK : -ENOMEM;
|
|||
* Address Environment Interfaces
|
||||
*
|
||||
* Low-level interfaces used in binfmt/ to instantiate tasks with address
|
||||
* environments. These interfaces all operate on task_addrenv_t which is an
|
||||
* abstract representation of the address environment and must be provided
|
||||
* by arch/arch.h is CONFIG_ADDRENV is defined.
|
||||
* environments. These interfaces all operate on type group_addrenv_t which
|
||||
* is an abstract representation of a task group's address environment and
|
||||
* must be defined in arch/arch.h if CONFIG_ADDRENV is defined.
|
||||
*
|
||||
* up_addrenv_create - Create an address environment
|
||||
* up_addrenv_destroy - Destroy an address environment.
|
||||
* up_addrenv_vaddr - Returns the virtual base address of the address
|
||||
* environment
|
||||
* up_addrenv_select - Instantiate an address environment
|
||||
* up_addrenv_destroy - Destroy an address environment.
|
||||
* up_addrenv_assign - Assign an address environment to a TCB
|
||||
* up_addrenv_restore - Restore an address environment
|
||||
* up_addrenv_assign - Assign an address environment to a group
|
||||
*
|
||||
* Higher-level interfaces used by the tasking logic. These interfaces are
|
||||
* used by the functions in sched/ and all operate on the TCB which as been
|
||||
* assigned an address environment by up_addrenv_assign().
|
||||
* used by the functions in sched/ and all operate on the thread which whose
|
||||
* group been assigned an address environment by up_addrenv_assign().
|
||||
*
|
||||
* up_addrenv_share - Clone the address environment assigned to one TCB
|
||||
* up_addrenv_attach - Clone the address environment assigned to one TCB
|
||||
* to another. This operation is done when a pthread
|
||||
* is created that share's the same address
|
||||
* environment.
|
||||
* up_addrenv_release - Release the TCBs reference to an address
|
||||
* environment when a task/thread exists.
|
||||
* up_addrenv_detach - Release the threads reference to an address
|
||||
* environment when a task/thread exits.
|
||||
*
|
||||
****************************************************************************/
|
||||
/****************************************************************************
|
||||
* Name: up_addrenv_create
|
||||
*
|
||||
* Description:
|
||||
* This function is called from the binary loader logic when a new
|
||||
* task is created in order to instantiate an address environment for the
|
||||
* task. up_addrenv_create is essentially the allocator of the physical
|
||||
* This function is called when a new task is created in order to
|
||||
* instantiate an address environment for the new task group.
|
||||
* up_addrenv_create() is essentially the allocator of the physical
|
||||
* memory for the new task.
|
||||
*
|
||||
* Input Parameters:
|
||||
|
@ -223,7 +224,7 @@ return g_physhandle ? OK : -ENOMEM;
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_addrenv_create(size_t envsize, FAR task_addrenv_t *addrenv)
|
||||
int up_addrenv_create(size_t envsize, FAR group_addrenv_t *addrenv)
|
||||
{
|
||||
FAR struct z180_cbr_s *cbr;
|
||||
irqstate_t flags;
|
||||
|
@ -280,7 +281,7 @@ int up_addrenv_create(size_t envsize, FAR task_addrenv_t *addrenv)
|
|||
|
||||
cbr->cbr = (uint8_t)alloc;
|
||||
cbr->pages = (uint8_t)npages;
|
||||
*addrenv = (task_addrenv_t)cbr;
|
||||
*addrenv = (group_addrenv_t)cbr;
|
||||
|
||||
irqrestore(flags);
|
||||
return OK;
|
||||
|
@ -293,6 +294,42 @@ errout_with_irq:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_addrenv_destroy
|
||||
*
|
||||
* Description:
|
||||
* This function is called when a final thread leaves the task group and
|
||||
* the task group is destroyed. This function then destroys the defunct
|
||||
* address environment, releasing the underlying physical memory.
|
||||
*
|
||||
* Input Parameters:
|
||||
* addrenv - The address environment to be destroyed.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_addrenv_destroy(group_addrenv_t addrenv)
|
||||
{
|
||||
FAR struct z180_cbr_s *cbr = (FAR struct z180_cbr_s *)addrenv;
|
||||
|
||||
DEBUGASSERT(cbr);
|
||||
|
||||
/* Free the physical address space backing up the mapping */
|
||||
|
||||
#ifdef CONFIG_GRAN_SINGLE
|
||||
gran_free((FAR void *)cbr->cbr, cbr->pages);
|
||||
#else
|
||||
gran_free(g_physhandle, (FAR void *)cbr->cbr, cbr->pages);
|
||||
#endif
|
||||
|
||||
/* And make the CBR structure available for re-use */
|
||||
|
||||
z180_mmu_freecbr(cbr);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_addrenv_vaddr
|
||||
*
|
||||
|
@ -311,7 +348,7 @@ errout_with_irq:
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_addrenv_vaddr(FAR task_addrenv_t addrenv, FAR void **vaddr)
|
||||
int up_addrenv_vaddr(FAR group_addrenv_t addrenv, FAR void **vaddr)
|
||||
{
|
||||
return CONFIG_Z180_COMMON1AREA_VIRTBASE;
|
||||
}
|
||||
|
@ -334,14 +371,14 @@ int up_addrenv_vaddr(FAR task_addrenv_t addrenv, FAR void **vaddr)
|
|||
* This may be used with up_addrenv_restore() to restore the original
|
||||
* address environment that was in place before up_addrenv_select() was
|
||||
* called. Note that this may be a task agnostic, hardware
|
||||
* representation that is different from task_addrenv_t.
|
||||
* representation that is different from group_addrenv_t.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_addrenv_select(task_addrenv_t addrenv, hw_addrenv_t *oldenv)
|
||||
int up_addrenv_select(group_addrenv_t addrenv, hw_addrenv_t *oldenv)
|
||||
{
|
||||
FAR struct z180_cbr_s *cbr = (FAR struct z180_cbr_s *)addrenv;
|
||||
irqstate_t flags;
|
||||
|
@ -383,127 +420,76 @@ int up_addrenv_restore(hw_addrenv_t oldenv)
|
|||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_addrenv_destroy
|
||||
*
|
||||
* Description:
|
||||
* Called from the binary loader loader during error handling to destroy
|
||||
* the address environment previously created by up_addrenv_create().
|
||||
*
|
||||
* Input Parameters:
|
||||
* addrenv - The representation of the task address environment previously
|
||||
* returned by up_addrenv_create.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_addrenv_destroy(task_addrenv_t addrenv)
|
||||
{
|
||||
FAR struct z180_cbr_s *cbr = (FAR struct z180_cbr_s *)addrenv;
|
||||
|
||||
DEBUGASSERT(cbr);
|
||||
|
||||
/* Free the physical address space backing up the mapping */
|
||||
|
||||
#ifdef CONFIG_GRAN_SINGLE
|
||||
gran_free((FAR void *)cbr->cbr, cbr->pages);
|
||||
#else
|
||||
gran_free(g_physhandle, (FAR void *)cbr->cbr, cbr->pages);
|
||||
#endif
|
||||
|
||||
/* And make the CBR structure available for re-use */
|
||||
|
||||
z180_mmu_freecbr(cbr);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_addrenv_assign
|
||||
*
|
||||
* Description:
|
||||
* Assign an address environment to a TCB.
|
||||
* Assign an address environment to a task group.
|
||||
*
|
||||
* Input Parameters:
|
||||
* addrenv - The representation of the task address environment previously
|
||||
* returned by up_addrenv_create.
|
||||
* tcb - The TCB of the task to receive the address environment.
|
||||
* returned by up_addrenv_create().
|
||||
* group - The task group to receive the address environment.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_addrenv_assign(task_addrenv_t addrenv, FAR struct tcb_s *tcb)
|
||||
int up_addrenv_assign(group_addrenv_t addrenv, FAR struct task_group_s *group)
|
||||
{
|
||||
FAR struct z180_cbr_s *cbr = (FAR struct z180_cbr_s *)addrenv;
|
||||
|
||||
/* Make sure that there is no address environment in place on this TCB */
|
||||
|
||||
DEBUGASSERT(cbr && tcb->xcp.cbr == NULL);
|
||||
DEBUGASSERT(addrenv && group->addrenv == NULL);
|
||||
|
||||
/* Save the CBR strucure in the TCB. This is an atomic operation so no
|
||||
/* Save the CBR structure in the group. This is an atomic operation so no
|
||||
* special precautions should be needed.
|
||||
*/
|
||||
|
||||
tcb->xcp.cbr = cbr;
|
||||
group->addrenv = addrenv;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_addrenv_share
|
||||
* Name: up_addrenv_attach
|
||||
*
|
||||
* Description:
|
||||
* This function is called from the core scheduler logic when a thread
|
||||
* is created that needs to share the address ennvironment of its parent
|
||||
* task. In this case, the parent's address environment needs to be
|
||||
* "cloned" for the child.
|
||||
* is created that needs to share the address environment of its task
|
||||
* group.
|
||||
*
|
||||
* Input Parameters:
|
||||
* ptcb - The TCB of the parent task that has the address environment.
|
||||
* ctcb - The TCB of the child thread needing the address environment.
|
||||
* group - The task group to which the new thread belongs.
|
||||
* tcb - The tcb of the thread needing the address environment.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_addrenv_share(FAR const struct tcb_s *ptcb, FAR struct tcb_s *ctcb)
|
||||
int up_addrenv_attach(FAR struct task_group_s *group, FAR struct tcb_s *tcb)
|
||||
{
|
||||
irqstate_t flags;
|
||||
/* There is nothing that needs to be done */
|
||||
|
||||
/* Make sure that the child has no address environment. It is okay if
|
||||
* if the parent does not have one.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(ctcb->xcp.cbr == NULL);
|
||||
|
||||
flags = irqsave();
|
||||
if (ptcb->xcp.cbr)
|
||||
{
|
||||
/* Clone the CBR by incrementing the reference counting and saving a
|
||||
* copy in the child thread's TCB.
|
||||
*/
|
||||
|
||||
ptcb->xcp.cbr->crefs++;
|
||||
ctcb->xcp.cbr = ptcb->xcp.cbr;
|
||||
}
|
||||
|
||||
irqrestore(flags);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_addrenv_release
|
||||
* Name: up_addrenv_detach
|
||||
*
|
||||
* Description:
|
||||
* This function is called when a task or thread exits in order to release
|
||||
* its reference to an address environment. When there are no further
|
||||
* references to an address environment, that address environment should
|
||||
* be destroyed.
|
||||
* its reference to an address environment. The address environment,
|
||||
* however, should persist until up_addrenv_destroy() is called when the
|
||||
* task group is itself destroyed. Any resources unique to this thread
|
||||
* may be destroyed now.
|
||||
*
|
||||
* NOTE: In some platforms, nothing will need to be done in this case.
|
||||
* Simply being a member of the group that has the address environment
|
||||
* may be sufficient.
|
||||
*
|
||||
* Input Parameters:
|
||||
* group - The group to which the thread belonged.
|
||||
* tcb - The TCB of the task or thread whose the address environment will
|
||||
* be released.
|
||||
*
|
||||
|
@ -512,39 +498,10 @@ int up_addrenv_share(FAR const struct tcb_s *ptcb, FAR struct tcb_s *ctcb)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_addrenv_release(FAR struct tcb_s *tcb)
|
||||
int up_addrenv_detach(FAR struct task_group_s *group,
|
||||
FAR struct task_group_s *tcb);
|
||||
{
|
||||
FAR struct z180_cbr_s *cbr;
|
||||
irqstate_t flags;
|
||||
/* There is nothing that needs to be done */
|
||||
|
||||
/* Check if the task has an address environment. */
|
||||
|
||||
flags = irqsave();
|
||||
cbr = tcb->xcp.cbr;
|
||||
if (cbr)
|
||||
{
|
||||
/* Nullify the reference to the CBR structure and decrement the number
|
||||
* of references on the CBR.
|
||||
*/
|
||||
|
||||
tcb->xcp.cbr = NULL;
|
||||
|
||||
/* If the reference count would decrement to zero, then free the CBR
|
||||
* structure.
|
||||
*/
|
||||
|
||||
if (cbr->crefs <= 1)
|
||||
{
|
||||
up_addrenv_destroy(cbr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, just decrement the reference count */
|
||||
|
||||
cbr->crefs--;
|
||||
}
|
||||
}
|
||||
|
||||
irqrestore(flags);
|
||||
return OK;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* binfmt/binfmt_execmodule.c
|
||||
*
|
||||
* Copyright (C) 2009, 2013 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2009, 2013-2014 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -205,10 +205,10 @@ int exec_module(FAR const struct binary_s *binp)
|
|||
up_initial_state(&tcb->cmn);
|
||||
#endif
|
||||
|
||||
/* Assign the address environment to the task */
|
||||
/* Assign the address environment to the new task group */
|
||||
|
||||
#ifdef CONFIG_ADDRENV
|
||||
ret = up_addrenv_assign(binp->addrenv, &tcb->cmn);
|
||||
ret = up_addrenv_assign(binp->addrenv, tcb->group);
|
||||
if (ret < 0)
|
||||
{
|
||||
err = -ret;
|
||||
|
|
|
@ -669,27 +669,27 @@ void up_allocate_kheap(FAR void **heap_start, size_t *heap_size);
|
|||
* Address Environment Interfaces
|
||||
*
|
||||
* Low-level interfaces used in binfmt/ to instantiate tasks with address
|
||||
* environments. These interfaces all operate on type task_addrenv_t which
|
||||
* is an abstract representation of a task's address environment and must be
|
||||
* defined in arch/arch.h if CONFIG_ADDRENV is defined.
|
||||
* environments. These interfaces all operate on type group_addrenv_t which
|
||||
* is an abstract representation of a task group's address environment and
|
||||
* must be defined in arch/arch.h if CONFIG_ADDRENV is defined.
|
||||
*
|
||||
* up_addrenv_create - Create an address environment
|
||||
* up_addrenv_destroy - Destroy an address environment.
|
||||
* up_addrenv_vaddr - Returns the virtual base address of the address
|
||||
* environment
|
||||
* up_addrenv_select - Instantiate an address environment
|
||||
* up_addrenv_restore - Restore an address environment
|
||||
* up_addrenv_destroy - Destroy an address environment.
|
||||
* up_addrenv_assign - Assign an address environment to a TCB
|
||||
* up_addrenv_assign - Assign an address environment to a group
|
||||
*
|
||||
* Higher-level interfaces used by the tasking logic. These interfaces are
|
||||
* used by the functions in sched/ and all operate on the TCB which as been
|
||||
* assigned an address environment by up_addrenv_assign().
|
||||
* used by the functions in sched/ and all operate on the thread which whose
|
||||
* group been assigned an address environment by up_addrenv_assign().
|
||||
*
|
||||
* up_addrenv_share - Clone the address environment assigned to one TCB
|
||||
* up_addrenv_attach - Clone the address environment assigned to one TCB
|
||||
* to another. This operation is done when a pthread
|
||||
* is created that share's the same address
|
||||
* environment.
|
||||
* up_addrenv_release - Release the TCBs reference to an address
|
||||
* up_addrenv_detach - Release the threads reference to an address
|
||||
* environment when a task/thread exits.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
@ -697,9 +697,9 @@ void up_allocate_kheap(FAR void **heap_start, size_t *heap_size);
|
|||
* Name: up_addrenv_create
|
||||
*
|
||||
* Description:
|
||||
* This function is called from the binary loader logic when a new
|
||||
* task is created in order to instantiate an address environment for the
|
||||
* task. up_addrenv_create is essentially the allocator of the physical
|
||||
* This function is called when a new task is created in order to
|
||||
* instantiate an address environment for the new task group.
|
||||
* up_addrenv_create() is essentially the allocator of the physical
|
||||
* memory for the new task.
|
||||
*
|
||||
* Input Parameters:
|
||||
|
@ -714,7 +714,27 @@ void up_allocate_kheap(FAR void **heap_start, size_t *heap_size);
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ADDRENV
|
||||
int up_addrenv_create(size_t envsize, FAR task_addrenv_t *addrenv);
|
||||
int up_addrenv_create(size_t envsize, FAR group_addrenv_t *addrenv);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_addrenv_destroy
|
||||
*
|
||||
* Description:
|
||||
* This function is called when a final thread leaves the task group and
|
||||
* the task group is destroyed. This function then destroys the defunct
|
||||
* address environment, releasing the underlying physical memory.
|
||||
*
|
||||
* Input Parameters:
|
||||
* addrenv - The address environment to be destroyed.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ADDRENV
|
||||
int up_addrenv_destroy(group_addrenv_t addrenv);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -736,17 +756,17 @@ int up_addrenv_create(size_t envsize, FAR task_addrenv_t *addrenv);
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ADDRENV
|
||||
int up_addrenv_vaddr(FAR task_addrenv_t addrenv, FAR void **vaddr);
|
||||
int up_addrenv_vaddr(FAR group_addrenv_t addrenv, FAR void **vaddr);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_addrenv_select
|
||||
*
|
||||
* Description:
|
||||
* After an address environment has been established for a task (via
|
||||
* After an address environment has been established for a task group (via
|
||||
* up_addrenv_create(). This function may be called to to instantiate
|
||||
* that address environment in the virtual address space. this might be
|
||||
* necessary, for example, to load the code for the task from a file or
|
||||
* necessary, for example, to load the code for the task group from a file or
|
||||
* to access address environment private data.
|
||||
*
|
||||
* Input Parameters:
|
||||
|
@ -757,7 +777,7 @@ int up_addrenv_vaddr(FAR task_addrenv_t addrenv, FAR void **vaddr);
|
|||
* This may be used with up_addrenv_restore() to restore the original
|
||||
* address environment that was in place before up_addrenv_select() was
|
||||
* called. Note that this may be a task agnostic, hardware
|
||||
* representation that is different from task_addrenv_t.
|
||||
* representation that is different from group_addrenv_t.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
|
@ -765,15 +785,15 @@ int up_addrenv_vaddr(FAR task_addrenv_t addrenv, FAR void **vaddr);
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ADDRENV
|
||||
int up_addrenv_select(task_addrenv_t addrenv, hw_addrenv_t *oldenv);
|
||||
int up_addrenv_select(group_addrenv_t addrenv, hw_addrenv_t *oldenv);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_addrenv_restore
|
||||
*
|
||||
* Description:
|
||||
* After an address environment has been temporarilty instantiated by
|
||||
* up_addrenv_select, this function may be called to to restore the
|
||||
* After an address environment has been temporarily instantiated by
|
||||
* up_addrenv_select(), this function may be called to to restore the
|
||||
* original address environment.
|
||||
*
|
||||
* Input Parameters:
|
||||
|
@ -789,36 +809,16 @@ int up_addrenv_select(task_addrenv_t addrenv, hw_addrenv_t *oldenv);
|
|||
int up_addrenv_restore(hw_addrenv_t oldenv);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_addrenv_destroy
|
||||
*
|
||||
* Description:
|
||||
* Called from the binary loader loader during error handling to destroy
|
||||
* the address environment previously created by up_addrenv_create().
|
||||
*
|
||||
* Input Parameters:
|
||||
* addrenv - The representation of the task address environment previously
|
||||
* returned by up_addrenv_create.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ADDRENV
|
||||
int up_addrenv_destroy(task_addrenv_t addrenv);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_addrenv_assign
|
||||
*
|
||||
* Description:
|
||||
* Assign an address environment to a TCB.
|
||||
* Assign an address environment to a new task group.
|
||||
*
|
||||
* Input Parameters:
|
||||
* addrenv - The representation of the task address environment previously
|
||||
* returned by up_addrenv_create.
|
||||
* tcb - The TCB of the task to receive the address environment.
|
||||
* returned by up_addrenv_create().
|
||||
* group - The new task group to receive the address environment.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
|
@ -826,21 +826,24 @@ int up_addrenv_destroy(task_addrenv_t addrenv);
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ADDRENV
|
||||
int up_addrenv_assign(task_addrenv_t addrenv, FAR struct tcb_s *tcb);
|
||||
int up_addrenv_assign(group_addrenv_t addrenv, FAR struct task_group_s *group);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_addrenv_share
|
||||
* Name: up_addrenv_attach
|
||||
*
|
||||
* Description:
|
||||
* This function is called from the core scheduler logic when a thread
|
||||
* is created that needs to share the address ennvironment of its parent
|
||||
* task. In this case, the parent's address environment needs to be
|
||||
* "cloned" for the child.
|
||||
* is created that needs to share the address environment of its task
|
||||
* group.
|
||||
*
|
||||
* NOTE: In some platforms, nothing will need to be done in this case.
|
||||
* Simply being a member of the group that has the address environment
|
||||
* may be sufficient.
|
||||
*
|
||||
* Input Parameters:
|
||||
* ptcb - The TCB of the parent task that has the address environment.
|
||||
* ctcb - The TCB of the child thread needing the address environment.
|
||||
* group - The task group to which the new thread belongs.
|
||||
* tcb - The TCB of the thread needing the address environment.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
|
@ -848,19 +851,25 @@ int up_addrenv_assign(task_addrenv_t addrenv, FAR struct tcb_s *tcb);
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ADDRENV
|
||||
int up_addrenv_share(FAR const struct tcb_s *ptcb, FAR struct tcb_s *ctcb);
|
||||
int up_addrenv_attach(FAR struct task_group_s *group, FAR struct tcb_s *tcb);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_addrenv_release
|
||||
* Name: up_addrenv_detach
|
||||
*
|
||||
* Description:
|
||||
* This function is called when a task or thread exits in order to release
|
||||
* its reference to an address environment. When there are no further
|
||||
* references to an address environment, that address environment should
|
||||
* be destroyed.
|
||||
* its reference to an address environment. The address environment,
|
||||
* however, should persist until up_addrenv_destroy() is called when the
|
||||
* task group is itself destroyed. Any resources unique to this thread
|
||||
* may be destroyed now.
|
||||
*
|
||||
* NOTE: In some platforms, nothing will need to be done in this case.
|
||||
* Simply being a member of the group that has the address environment
|
||||
* may be sufficient.
|
||||
*
|
||||
* Input Parameters:
|
||||
* group - The group to which the thread belonged.
|
||||
* tcb - The TCB of the task or thread whose the address environment will
|
||||
* be released.
|
||||
*
|
||||
|
@ -870,7 +879,8 @@ int up_addrenv_share(FAR const struct tcb_s *ptcb, FAR struct tcb_s *ctcb);
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ADDRENV
|
||||
int up_addrenv_release(FAR struct tcb_s *tcb);
|
||||
int up_addrenv_detach(FAR struct task_group_s *group,
|
||||
FAR struct task_group_s *tcb);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -125,7 +125,7 @@ struct binary_s
|
|||
*/
|
||||
|
||||
#ifdef CONFIG_ADDRENV
|
||||
task_addrenv_t addrenv; /* Task address environment */
|
||||
group_addrenv_t addrenv; /* Task group address environment */
|
||||
#endif
|
||||
|
||||
size_t mapsize; /* Size of the mapped address region (needed for munmap) */
|
||||
|
|
|
@ -131,8 +131,8 @@ struct elf_loadinfo_s
|
|||
*/
|
||||
|
||||
#ifdef CONFIG_ADDRENV
|
||||
task_addrenv_t addrenv; /* Task address environment */
|
||||
hw_addrenv_t oldenv; /* Saved hardware address environment */
|
||||
group_addrenv_t addrenv; /* Task group address environment */
|
||||
hw_addrenv_t oldenv; /* Saved hardware address environment */
|
||||
#endif
|
||||
|
||||
uint16_t symtabidx; /* Symbol table section index */
|
||||
|
|
|
@ -103,13 +103,13 @@ struct nxflat_loadinfo_s
|
|||
*/
|
||||
|
||||
#ifdef CONFIG_ADDRENV
|
||||
task_addrenv_t addrenv; /* Task address environment */
|
||||
hw_addrenv_t oldenv; /* Saved hardware address environment */
|
||||
group_addrenv_t addrenv; /* Task group address environment */
|
||||
hw_addrenv_t oldenv; /* Saved hardware address environment */
|
||||
#endif
|
||||
|
||||
/* File descriptors */
|
||||
|
||||
int filfd; /* Descriptor for the file being loaded */
|
||||
int filfd; /* Descriptor for the file being loaded */
|
||||
|
||||
/* This is a copy of the NXFLAT header (still in network order) */
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/********************************************************************************
|
||||
* include/nuttx/sched.h
|
||||
*
|
||||
* Copyright (C) 2007-2013 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2014 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -99,6 +99,8 @@
|
|||
# define HAVE_TASK_GROUP 1 /* Sockets */
|
||||
# elif !defined(CONFIG_DISABLE_MQUEUE)
|
||||
# define HAVE_TASK_GROUP 1 /* Message queues */
|
||||
# elif defined(CONFIG_ADDRENV)
|
||||
# define HAVE_TASK_GROUP 1 /* Address environment */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
@ -264,25 +266,24 @@ struct dspace_s
|
|||
|
||||
/* struct task_group_s ***********************************************************/
|
||||
/* All threads created by pthread_create belong in the same task group (along with
|
||||
* the thread of the original task). struct task_group_s is a shared, "breakaway"
|
||||
* structure referenced by each TCB.
|
||||
* the thread of the original task). struct task_group_s is a shared structure
|
||||
* referenced by the TCB of each thread that is a member of the task group.
|
||||
*
|
||||
* This structure should contain *all* resources shared by tasks and threads that
|
||||
* belong to the same task group:
|
||||
*
|
||||
* Child exit status
|
||||
* Environment varibles
|
||||
* Environment variables
|
||||
* PIC data space and address environments
|
||||
* File descriptors
|
||||
* FILE streams
|
||||
* Sockets
|
||||
*
|
||||
* Currenty, however, this implementation only applies to child exit status.
|
||||
* Address environments.
|
||||
*
|
||||
* Each instance of struct task_group_s is reference counted. Each instance is
|
||||
* created with a reference count of one. The reference incremeneted when each
|
||||
* created with a reference count of one. The reference incremented when each
|
||||
* thread joins the group and decremented when each thread exits, leaving the
|
||||
* group. When the refernce count decrements to zero, the struc task_group_s
|
||||
* group. When the reference count decrements to zero, the struct task_group_s
|
||||
* is free.
|
||||
*/
|
||||
|
||||
|
@ -313,9 +314,9 @@ struct task_group_s
|
|||
FAR pid_t *tg_members; /* Members of the group */
|
||||
#endif
|
||||
|
||||
/* atexit/on_exit support ****************************************************/
|
||||
|
||||
#if defined(CONFIG_SCHED_ATEXIT) && !defined(CONFIG_SCHED_ONEXIT)
|
||||
/* atexit support ************************************************************/
|
||||
|
||||
# if defined(CONFIG_SCHED_ATEXIT_MAX) && CONFIG_SCHED_ATEXIT_MAX > 1
|
||||
atexitfunc_t tg_atexitfunc[CONFIG_SCHED_ATEXIT_MAX];
|
||||
# else
|
||||
|
@ -324,6 +325,8 @@ struct task_group_s
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_SCHED_ONEXIT
|
||||
/* on_exit support ***********************************************************/
|
||||
|
||||
# if defined(CONFIG_SCHED_ONEXIT_MAX) && CONFIG_SCHED_ONEXIT_MAX > 1
|
||||
onexitfunc_t tg_onexitfunc[CONFIG_SCHED_ONEXIT_MAX];
|
||||
FAR void *tg_onexitarg[CONFIG_SCHED_ONEXIT_MAX];
|
||||
|
@ -333,23 +336,22 @@ struct task_group_s
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS)
|
||||
/* Child exit status **********************************************************/
|
||||
|
||||
#if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS)
|
||||
FAR struct child_status_s *tg_children; /* Head of a list of child status */
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_SCHED_HAVE_PARENT)
|
||||
/* waitpid support ************************************************************/
|
||||
/* Simple mechanism used only when there is no support for SIGCHLD */
|
||||
|
||||
#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_SCHED_HAVE_PARENT)
|
||||
sem_t tg_exitsem; /* Support for waitpid */
|
||||
int *tg_statloc; /* Location to return exit status */
|
||||
#endif
|
||||
|
||||
/* Pthreads *******************************************************************/
|
||||
|
||||
#ifndef CONFIG_DISABLE_PTHREAD
|
||||
/* Pthreads *******************************************************************/
|
||||
/* Pthread join Info: */
|
||||
sem_t tg_joinsem; /* Mutually exclusive access to join data */
|
||||
FAR struct join_s *tg_joinhead; /* Head of a list of join data */
|
||||
|
@ -357,15 +359,15 @@ struct task_group_s
|
|||
uint8_t tg_nkeys; /* Number pthread keys allocated */
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
/* POSIX Signal Control Fields ************************************************/
|
||||
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
sq_queue_t sigpendingq; /* List of pending signals */
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DISABLE_ENVIRON
|
||||
/* Environment variables ******************************************************/
|
||||
|
||||
#ifndef CONFIG_DISABLE_ENVIRON
|
||||
size_t tg_envsize; /* Size of environment string allocation */
|
||||
FAR char *tg_envp; /* Allocated environment strings */
|
||||
#endif
|
||||
|
@ -376,19 +378,19 @@ struct task_group_s
|
|||
* life of the PIC data is managed.
|
||||
*/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
/* File descriptors ***********************************************************/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
struct filelist tg_filelist; /* Maps file descriptor to file */
|
||||
#endif
|
||||
|
||||
#if CONFIG_NFILE_STREAMS > 0
|
||||
/* FILE streams ***************************************************************/
|
||||
/* In a flat, single-heap build. The stream list is allocated with this
|
||||
* structure. But kernel mode with a kernel allocator, it must be separately
|
||||
* allocated using a user-space allocator.
|
||||
*/
|
||||
|
||||
#if CONFIG_NFILE_STREAMS > 0
|
||||
#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
|
||||
FAR struct streamlist *tg_streamlist;
|
||||
#else
|
||||
|
@ -396,16 +398,24 @@ struct task_group_s
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||
/* Sockets ********************************************************************/
|
||||
|
||||
#if CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||
struct socketlist tg_socketlist; /* Maps socket descriptor to socket */
|
||||
#endif
|
||||
/* POSIX Named Message Queue Fields *******************************************/
|
||||
|
||||
#ifndef CONFIG_DISABLE_MQUEUE
|
||||
/* POSIX Named Message Queue Fields *******************************************/
|
||||
|
||||
sq_queue_t tg_msgdesq; /* List of opened message queues */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ADDRENV
|
||||
/* POSIX Named Message Queue Fields *******************************************/
|
||||
/* POSIX Named Message Queue Fields *******************************************/
|
||||
|
||||
group_addrenv_t addrenv; /* Task group address environment */
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -508,7 +518,7 @@ struct tcb_s
|
|||
int pterrno; /* Current per-thread errno */
|
||||
|
||||
/* State save areas ***********************************************************/
|
||||
/* The form and content of these fields are processor-specific. */
|
||||
/* The form and content of these fields are platform-specific. */
|
||||
|
||||
struct xcptcontext xcp; /* Interrupt register save area */
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* sched/pthread/pthread_create.c
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2011, 2013 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2011, 2013-2014 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -254,11 +254,11 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr,
|
|||
return ENOMEM;
|
||||
}
|
||||
|
||||
#ifdef HAVE_TASK_GROUP
|
||||
/* Bind the parent's group to the new TCB (we have not yet joined the
|
||||
* group).
|
||||
*/
|
||||
|
||||
#ifdef HAVE_TASK_GROUP
|
||||
ret = group_bind(ptcb);
|
||||
if (ret < 0)
|
||||
{
|
||||
|
@ -267,14 +267,11 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr,
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Share the address environment of the parent task. NOTE: Only tasks
|
||||
* created throught the nuttx/binfmt loaders may have an address
|
||||
* environment.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ADDRENV
|
||||
ret = up_addrenv_share((FAR const struct tcb_s *)g_readytorun.head,
|
||||
(FAR struct tcb_s *)ptcb);
|
||||
/* Share the address environment of the parent task group. */
|
||||
|
||||
ret = up_addrenv_attach(ptcb->group,
|
||||
(FAR const struct tcb_s *)g_readytorun.head);
|
||||
if (ret < 0)
|
||||
{
|
||||
errcode = -ret;
|
||||
|
@ -323,9 +320,9 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr,
|
|||
priority = SCHED_FIFO;
|
||||
}
|
||||
|
||||
#if CONFIG_RR_INTERVAL > 0
|
||||
/* Get the scheduler policy for this thread */
|
||||
|
||||
#if CONFIG_RR_INTERVAL > 0
|
||||
policy = sched_getscheduler(0);
|
||||
if (policy == ERROR)
|
||||
{
|
||||
|
@ -358,9 +355,9 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr,
|
|||
|
||||
pthread_argsetup(ptcb, arg);
|
||||
|
||||
#ifdef HAVE_TASK_GROUP
|
||||
/* Join the parent's task group */
|
||||
|
||||
#ifdef HAVE_TASK_GROUP
|
||||
ret = group_join(ptcb);
|
||||
if (ret < 0)
|
||||
{
|
||||
|
@ -373,11 +370,11 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr,
|
|||
|
||||
ptcb->joininfo = (FAR void *)pjoin;
|
||||
|
||||
#if CONFIG_RR_INTERVAL > 0
|
||||
/* If round robin scheduling is selected, set the appropriate flag
|
||||
* in the TCB.
|
||||
*/
|
||||
|
||||
#if CONFIG_RR_INTERVAL > 0
|
||||
if (policy == SCHED_RR)
|
||||
{
|
||||
ptcb->cmn.flags |= TCB_FLAG_ROUND_ROBIN;
|
||||
|
|
|
@ -193,10 +193,10 @@ int sched_releasetcb(FAR struct tcb_s *tcb, uint8_t ttype)
|
|||
/* Release this thread's reference to the address environment */
|
||||
|
||||
#ifdef CONFIG_ADDRENV
|
||||
ret = up_addrenv_release(tcb);
|
||||
ret = up_addrenv_detach(tcp->group, tcb);
|
||||
#endif
|
||||
|
||||
/* Leave the group (if we did not already leady in task_exithook.c) */
|
||||
/* Leave the group (if we did not already leave in task_exithook.c) */
|
||||
|
||||
#ifdef HAVE_TASK_GROUP
|
||||
group_leave(tcb);
|
||||
|
|
Loading…
Reference in a new issue