[BACK]Return to kapi.html CVS log [TXT][DIR] Up to [local] / prex-old / doc / html / doc

File: [local] / prex-old / doc / html / doc / kapi.html (download) (as text)

Revision 1.1, Tue Jun 3 09:38:42 2008 UTC (15 years, 11 months ago) by nbrk
Branch point for: MAIN

Initial revision

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <title>Prex Kernel API Reference</title>
  <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
  <meta name="keywords" content="Prex, embedded, real-time, operating system, RTOS, open source, free">
  <meta name="author" content="Kohsuke Ohtani">
  <link rel="stylesheet" type="text/css" href="../default.css" media="screen">
  <link rel="stylesheet" type="text/css" href="../print.css" media="print">
</head>
<body>
<div id="top">
</div>
<div id="middle">

<table id="content" cellpadding="0" cellspacing="0">
  <tbody>

    <tr>
      <td id="header" colspan="2" valign="top">
        <table width="100%" border="0" cellspacing="0" cellpadding="0">
        <tr>
          <td id="logo">
            <a href="http://prex.sourceforge.net/">
            <img alt="Prex logo" src="../img/logo.gif" border="0"
            style="width: 281px; height: 56px;"></a>
          </td>
          <td id="brief" align="right" valign="bottom">
            An Open Source, Royalty-free,<br>
	    Real-time Operating System
          </td>
        </tr>
        </table>
      </td>
    </tr

    <tr>
      <td id="directory" style="vertical-align: top;">
      <a href="http://prex.sourceforge.net/">Prex Home</a> >
      <a href="index.html">Document Index</a> >
      Kernel API Reference
    </tr>
    <tr><td class="pad" colspan="2" style="vertical-align: top;"></td></tr>

    <tr>
      <td id="main" style="vertical-align: top;">
      <h1>Prex Kernel API Reference</h1>

<i>Version 1.7.0, 2007/12/24</i><br>
<br>

<h3>Table of Contents</h3>

<ul>
<li><a href="#intro">Introduction</a></li>
</ul>

<ul>
<li><a href="#gen">General Information</a>
  <ul>
  <li><a href="#type">Data Types</a></li>
  <li><a href="#err">Error Numbers</a></li>
  </ul>
</li>
</ul>

<ul>
<li><a href="#obj">Object</a>
  <ul>
  <li><a href="#obj0">object_create</a></li>
  <li><a href="#obj1">object_delete</a></li>
  <li><a href="#obj2">object_lookup</a></li>
  </ul>
</li>
</ul>

<ul>
<li><a href="#msg">Message</a>
  <ul>
  <li><a href="#msg0">msg_send</a></li>
  <li><a href="#msg1">msg_receive</a></li>
  <li><a href="#msg2">msg_reply</a></li>
  </ul>
</li>
</ul>

<ul>
<li><a href="#task">Task</a>
  <ul>
  <li><a href="#task0">task_create</a></li>
  <li><a href="#task1">task_terminate</a></li>
  <li><a href="#task2">task_self</a></li>
  <li><a href="#task3">task_suspend</a></li>
  <li><a href="#task4">task_resume</a></li>
  <li><a href="#task5">task_name</a></li>
  <li><a href="#task6">task_getcap</a></li>
  <li><a href="#task7">task_setcap</a></li>
  </ul>
</li>
</ul>

<ul>
<li><a href="#thr">Thread</a>
  <ul>
  <li><a href="#thr0">thread_create</a></li>
  <li><a href="#thr1">thread_terminate</a></li>
  <li><a href="#thr2">thread_load</a></li>
  <li><a href="#thr3">thread_self</a></li>
  <li><a href="#thr4">thread_yield</a></li>
  <li><a href="#thr5">thread_suspend</a></li>
  <li><a href="#thr6">thread_resume</a></li>
  <li><a href="#thr7">thread_schedparam</a></li>
  </ul>
</li>
</ul>

<ul>
<li><a href="#vm">Virtual Memory</a>
  <ul>
  <li><a href="#vm0">vm_allocate</a></li>
  <li><a href="#vm1">vm_free</a></li>
  <li><a href="#vm2">vm_attribute</a></li>
  <li><a href="#vm3">vm_map</a></li>
  </ul>
</li>
</ul>

<ul>
<li><a href="#tmr">Timer</a>
  <ul>
  <li><a href="#tmr0">timer_sleep</a></li>
  <li><a href="#tmr1">timer_alarm</a></li>
  <li><a href="#tmr2">timer_periodic</a></li>
  <li><a href="#tmr3">timer_waitperiod</a></li>
  </ul>
</li>
</ul>

<ul>
<li><a href="#ex">Exception</a>
  <ul>
  <li><a href="#ex0">exception_setup</a></li>
  <li><a href="#ex1">exception_return</a></li>
  <li><a href="#ex2">exception_raise</a></li>
  <li><a href="#ex3">exception_wait</a></li>
  </ul>
</li>
</ul>

<ul>
<li><a href="#dev">Device</a>
  <ul>
  <li><a href="#dev0">device_open</a></li>
  <li><a href="#dev1">device_close</a></li>
  <li><a href="#dev2">device_read</a></li>
  <li><a href="#dev3">device_write</a></li>
  <li><a href="#dev4">device_ioctl</a></li>
  </ul>
</li>
</ul>

<ul>
<li><a href="#mu">Mutex</a>
  <ul>
  <li><a href="#mu0">mutex_init</a></li>
  <li><a href="#mu1">mutex_destroy</a></li>
  <li><a href="#mu2">mutex_trylock</a></li>
  <li><a href="#mu3">mutex_lock</a></li>
  <li><a href="#mu4">mutex_unlock</a></li>
  </ul>
</li>
</ul>

<ul>
<li><a href="#cv">Condition Variable</a>
  <ul>
  <li><a href="#cv0">cond_init</a></li>
  <li><a href="#cv1">cond_destroy</a></li>
  <li><a href="#cv2">cond_wait</a></li>
  <li><a href="#cv3">cond_signal</a></li>
  <li><a href="#cv4">cond_broadcast</a></li>
  </ul>
</li>
</ul>

<ul>
<li><a href="#sem">Semaphore</a>
  <ul>
  <li><a href="#sem0">sem_init</a></li>
  <li><a href="#sem1">sem_destroy</a></li>
  <li><a href="#sem2">sem_wait</a></li>
  <li><a href="#sem3">sem_trywait</a></li>
  <li><a href="#sem4">sem_post</a></li>
  <li><a href="#sem5">sem_getvalue</a></li>
  </ul>
</li>
</ul>

<ul>
<li><a href="#sys">System</a>
  <ul>
  <li><a href="#sys0">sys_log</a></li>
  <li><a href="#sys1">sys_panic</a></li>
  <li><a href="#sys2">sys_info</a></li>
  <li><a href="#sys3">sys_time</a></li>
  <li><a href="#sys4">sys_debug</a></li>
  </ul>

</ul>


<h2 id="intro">Introduction</h2>
<p>
The Prex Kernel API Reference define a programming interface
for the Prex applications.
This document includes the complete set of kernel services and the detailed
description.
</p>


<h2 id="gen">General Information</h2>

<h3 id="type">Data Types</h3>
<p>
The following data types are supported by the Prex kernel.
Each type represents ID of the kernel element.
</p>

<table border="1" width="60%" cellspacing="0">
<tbody>
<tr>
  <th>Data type</th>
  <th>Description</th>
</tr>
<tr>
  <td>object_t</td>
  <td>Used to identify a object.</td>
</tr>
<tr>
  <td>task_t</td>
  <td>Used to identify a task.</td>
</tr>
<tr>
  <td>thread_t</td>
  <td>Used to identify a thread.</td>
</tr>
<tr>
  <td>device_t</td>
  <td>Used to identify a device.</td>
</tr>
<tr>
  <td>mutex_t</td>
  <td>Used to identify a mutex.</td>
</tr>
<tr>
  <td>cond_t</td>
  <td>Used to identify a condition variable.</td>
</tr>
<tr>
  <td>sem_t</td>
  <td>Used to identify a semaphore.</td>
</tr>
<tr>
  <td>cap_t</td>
  <td>Used to represent a task capability.</td>
</tr>

</tbody>
</table>


<h3 id="err">Error Numbers</h3>
<p>
The definition of the Prex kernel error is compatible with the POSIX
error number. However, unlike POSIX, Prex does not use an errno variable
because errno is not MT-safe. So, most functions in kernel API will
provide an error number as a return value.
</p>
<p>
The following error names are used as the possible error number.
</p>
<dl>
<dt>[EPERM]</dt>
<dd>Operation not permitted.</dd>
<dt>[ENOENT]</dt>
<dd>No such file or directory.</dd>
<dt>[ESRCH]</dt>
<dd>No such process.</dd>
<dt>[EINTR]</dt>
<dd>Interrupted system call.</dd>
<dt>[EIO]</dt>
<dd>I/O error.</dd>
<dt>[ENXIO]</dt>
<dd>No such device or address.</dd>
<dt>[EAGAIN]</dt>
<dd>Try again.</dd>
<dt>[ENOMEM]</dt>
<dd>Out of memory.</dd>
<dt>[EACCES]</dt>
<dd>Permission denied.</dd>
<dt>[EFAULT]</dt>
<dd>Bad address.</dd>
<dt>[EBUSY]</dt>
<dd>Device or resource busy.</dd>
<dt>[EEXIST]</dt>
<dd>File exists.</dd>
<dt>[ENODEV]</dt>
<dd>No such device.</dd>
<dt>[EINVAL]</dt>
<dd>Invalid argument.</dd>
<dt>[ERANGE]</dt>
<dd>Math result not representable.</dd>
<dt>[EDEADLK]</dt>
<dd>Resource deadlock avoided.</dd>
<dt>[ENOSYS]</dt>
<dd>Function not implemented.</dd>
<dt>[ENAMETOOLONG]</dt>
<dd>File name too long.</dd>
<dt>[ETIMEDOUT]</dt>
<dd>Timed out.</dd>

</dl>

<h2 id="obj">Object</h2>

<h3 id="obj0">NAME</h3>
object_create() - create a new object

<h3>SYNOPSIS</h3>
<pre>
int object_create(const char *name, object_t *obj);
</pre>

<h3>DESCRIPTION</h3>
The object_create() function creates a new object.
The ID of the new object is stored in <i>obj</i> on success.
<br><br>
The name of the object must be unique in the system.
Or, the object can be created without name by setting NULL
as <i>name</i> argument. This object can be used as a private object
which can be accessed only by threads in the same task.

<h3>ERRORS</h3>
<dl>
<dt>[EFAULT]</dt>
<dd>The address of <i>name</i> or <i>obj</i> is inaccessible.</dd>
<dt>[ENAMETOOLONG]</dt>
<dd>The length of the <i>name</i> argument exceeds MAX_OBJNAME.</dd>
<dt>[EEXIST]</dt>
<dd>The named object already exists.</dd>
<dt>[ENOMEM]</dt>
<dd>The system is unable to allocate resources.</dd>
</dl>
<br>
<hr size="1">


<h3 id="obj1">NAME</h3>
object_delete() - delete an object

<h3>SYNOPSIS</h3>
<pre>
int object_delete(object_t obj);
</pre>

<h3>DESCRIPTION</h3>
The object_delete() function deletes the object specified by <i>obj</i>.
<br><br>
A thread can delete the object only when the target object is created
by the thread of the same task.
All pending messages related to the deleted object are automatically canceled.

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd>The specified <i>obj</i> is not a valid object ID.</dd>
<dt>[EACCESS]</dt>
<dd>The thread is not allowed to delete the object.</dd>
</dl>
<br>
<hr size="1">


<h3 id="obj2">NAME</h3>
object_lookup() - lookup an object

<h3>SYNOPSIS</h3>
<pre>
int object_lookup(const char *name, object_t *obj);
</pre>

<h3>DESCRIPTION</h3>
The object_lookup() function searches an object in the object name space.
The <i>name</i> argument is the null-terminated string.
The object ID is returned in <i>obj</i> on success.

<h3>ERRORS</h3>
<dl>
<dt>[EFAULT]</dt>
<dd>The address of <i>name</i> or <i>obj</i> is inaccessible.</dd>
<dt>[ESRCH]</dt>
<dd>The length of the <i>name</i> argument exceeds MAX_OBJNAME.</dd>
<dt>[ENOENT]</dt>
<dd>The specified object does not exist.</dd>
</dl>
<br>


<h2 id="msg">Message</h2>

<h3 id="msg0">NAME</h3>
msg_send() - send a message

<h3>SYNOPSIS</h3>
<pre>
int msg_send(object_t obj, void *msg, size_t size);
</pre>

<h3>DESCRIPTION</h3>
The msg_send() function sends a message to an object.
The caller thread will be blocked until any other thread receives
the message and calls msg_reply() for this object.
A thread can send a message to any object if it knows the object ID.
<br><br>
The <i>size</i> argument specifies the size of the message buffer to send.
<br><br>
The message is the binary data block which includes a message header.
The kernel does not touch the message body, and it is
necessary to recognize the predefined message format between sender
and receiver.

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd>The specified <i>obj</i> is not a valid object ID.</dd>
<dt>[EFAULT]</dt>
<dd>The buffer of <i>msg</i> is inaccessible.</dd>
<dt>[EDEADLK]</dt>
<dd><i>obj</i> is the object that the caller thread is receiving from now.</dd>
<dt>[EAGAIN]</dt>
<dd>The receiver thread has been terminated.</dd>
<dt>[EINTR]</dt>
<dd>The function was interrupted by an exception.</dd>
<dt>[EPERM]</dt>
<dd>The caller task is not an owner of the <i>obj</i>, but it
does not have CAP_IPC capability.</dd>
</dl>
<br>
<hr size="1">


<h3 id="msg1">NAME</h3>
msg_receive() - receive a message

<h3>SYNOPSIS</h3>
<pre>
int msg_receive(object_t obj, void *msg, size_t size);
</pre>

<h3>DESCRIPTION</h3>
The msg_receive() function receives a message from an object.
A thread can receive a message from the object which was created
by the thread in the same task. If the message has not arrived, the
caller thread blocks until any message comes in.
<br><br>
The <i>size</i> argument specifies the "maximum" size of the message
buffer to receive. If the sent message is larger than this size,
the kernel will automatically clip the message to the receive buffer size.
<br><br>
A thread can not receive the multiple messages at once.

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd>The specified <i>obj</i> is not a valid object ID.</dd>
<dt>[EACCESS]</dt>
<dd>The caller task is not the owner of the target object.</dd>
<dt>[EBUSY]</dt>
<dd>The caller thread does not finish the previous receive operation.</dd>
<dt>[EFAULT]</dt>
<dd>The buffer of <i>msg</i> is inaccessible.</dd>
<dt>[EINTR]</dt>
<dd>The function was interrupted by an exception.</dd>
</dl>
<br>
<hr size="1">


<h3 id="msg2">NAME</h3>
msg_reply() - reply to an object

<h3>SYNOPSIS</h3>
<pre>
int msg_reply(object_t obj, void *msg, size_t size);
</pre>

<h3>DESCRIPTION</h3>
The msg_reply() function sends a reply message to the object.
A thread must reply to the correct object that the thread
preciously received from. Otherwise, this function will be failed.
<br><br>
The <i>size</i> argument specifies the size of the message buffer to reply.

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd>The specified <i>obj</i> is not a valid object ID. Or, the sender
thread has been terminated.</dd>
<dt>[EFAULT]</dt>
<dd>The buffer of <i>msg</i> is inaccessible.</dd>
</dl>
<br>


<h2 id="task">Task</h2>

<h3 id="task0">NAME</h3>
task_create() - create a new task

<h3>SYNOPSIS</h3>
<pre>
int task_create(task_t parent, int vm_option, task_t *child);
</pre>

<h3>DESCRIPTION</h3>
The task_create() function create a new task.
If <i>vm_option</i> option can be one of the following:
<ul>
<li>VM_NEW - The new task has clean memory image.</li>
<li>VM_COPY - The new task will have the duplicated memory image with the parent task.</li>
<li>VM_SHARE - The new task will share the same memory image with the parent task.</li>
</ul>
The child task initially contains no threads.
So, the caller task must create new thread under the child task to
run it.
<br><br>
<i>vm_option</i> flag is supported only with MMU system. The created
task has always new memory map with NOMMU system.
<br><br>
The function returns the created task ID in <i>child</i>,
and child task will receive 0 as <i>child</i>.

<h3>ERRORS</h3>
<dl>
<dt>[ESRCH]</dt>
<dd>The specified <i>parent</i> is not a valid task ID.</dd>
<dt>[EFAULT]</dt>
<dd>The address of <i>child</i> is inaccessible.</dd>
<dt>[ENOMEM]</dt>
<dd>The system is unable to allocate resources.</dd>
<dt>[EPERM]</dt>
<dd>The specified <i>parent</i> is not a current task, but the caller
task does not have CAP_TASK capability.</dd>
</dl>
<br>
<hr size="1">


<h3 id="task1">NAME</h3>
task_terminate() - terminate a task

<h3>SYNOPSIS</h3>
<pre>
int task_terminate(task_t task);
</pre>

<h3>DESCRIPTION</h3>
The task_terminate() function terminates a task and deallocates all resource
for the task.
<br><br>
If the <i>task</i> argument point to the current task, this routine never returns.

<h3>ERRORS</h3>
<dl>
<dt>[ESRCH]</dt>
<dd>The specified <i>task</i> is not a valid task ID.</dd>
<dt>[EPERM]</dt>
<dd>The specified <i>task</i> is not a current task, but the caller
task does not have CAP_TASK capability.</dd>
</dl>
<br>
<hr size="1">


<h3 id="task2">NAME</h3>
task_self() - return task ID

<h3>SYNOPSIS</h3>
<pre>
task_t task_self(void);
</pre>

<h3>DESCRIPTION</h3>
The task_self() function returns ID of the current task.

<h3>RETURN VALUE</h3>
Current task ID.
<br>
<br>
<hr size="1">


<h3 id="task3">NAME</h3>
task_suspend() - suspend a task

<h3>SYNOPSIS</h3>
<pre>
int task_suspend(task_t task);
</pre>

<h3>DESCRIPTION</h3>
The task_suspend() function suspends all threads within the specified task.

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd>The specified <i>task</i> is not a valid task ID.</dd>
<dt>[ESRCH]</dt>
<dd>The specified <i>task</i> is not a current task, but the caller
task does not have CAP_TASK capability.</dd>
</dl>
<br>
<hr size="1">


<h3 id="task4">NAME</h3>
task_resume() - resume a task

<h3>SYNOPSIS</h3>
<pre>
int task_resume(task_t task);
</pre>

<h3>DESCRIPTION</h3>
The task_resume() function resumes all threads within the specified task.

<h3>ERRORS</h3>
<dl>
<dt>[ESRCH]</dt>
<dd>The specified <i>task</i> is not a valid task ID.</dd>
<dt>[EINVAL]</dt>
<dd>The specified <i>task</i> is not suspended now.</dd>
<dt>[EPERM]</dt>
<dd>The specified <i>task</i> is not a current task, but the caller
task does not have CAP_TASK capability.</dd>
</dl>
<br>
<hr size="1">


<h3 id="task5">NAME</h3>
task_name() - set task name

<h3>SYNOPSIS</h3>
<pre>
int task_name(task_t task, const char *name);
</pre>

<h3>DESCRIPTION</h3>
The task_name() function set the name of the specified task. The task name can
be changed at any time.
<br><br>
This function does not returns error even if the same task name already
exists in the system.

<h3>ERRORS</h3>
<dl>
<dt>[ESRCH]</dt>
<dd>The specified <i>task</i> is not a valid task ID.</dd>
<dt>[EFAULT]</dt>
<dd>The address of <i>name</i> is inaccessible.</dd>
<dt>[ENAMETOOLONG]</dt>
<dd>The length of the <i>name</i> argument exceeds MAX_TASKNAME.</dd>
<dt>[EPERM]</dt>
<dd>The specified <i>task</i> is not a current task, but the caller
task does not have CAP_TASK capability.</dd>
</dl>
<br>
<hr size="1">

<h3 id="task6">NAME</h3>
task_getcap() - get a task capability

<h3>SYNOPSIS</h3>
<pre>
int task_getcap(task_t task, cap_t *cap);
</pre>

<h3>DESCRIPTION</h3>
<p>
The task_getcap() function returns the capability of the
specified task.
</p>


<h3>ERRORS</h3>
<dl>
<dt>[ESRCH]</dt>
<dd>The specified <i>task</i> is not a valid task ID.</dd>
<dt>[EFAULT]</dt>
<dd>The address of <i>cap</i> is inaccessible.</dd>
</dl>
<br>


<hr size="1">

<h3 id="task7">NAME</h3>
task_setcap() - set a task capability

<h3>SYNOPSIS</h3>
<pre>
int task_setcap(task_t task, cap_t *cap);
</pre>

<h3>DESCRIPTION</h3>
<p>
The task_setcap() function set the capability of the
specified task.
</p>
<p>
The following task capabilities are supported.
</p>
<dl>
<dt>CAP_SETPCAP</dt>
<dd>Allow setting capability.</dd>
<dt>CAP_TASK</dt>
<dd>Allow controlling another task's execution.</dd>
<dt>CAP_MEMORY</dt>
<dd>Allow touching another task's memory.</dd>
<dt>CAP_KILL</dt>
<dd>Allow raising exception to another task.</dd>
<dt>CAP_SEMAPHORE</dt>
<dd>Allow accessing another task's semaphore.</dd>
<dt>CAP_NICE</dt>
<dd>Allow changing scheduling parameter.</dd>
<dt>CAP_IPC</dt>
<dd>Allow accessing another task's IPC object.</dd>
<dt>CAP_DEVIO</dt>
<dd>Allow device I/O operations.</dd>
<dt>CAP_POWER</dt>
<dd>Allow power control including shutdown.</dd>
<dt>CAP_TIME</dt>
<dd>Allow setting system time.</dd>
<dt>CAP_RAWIO</dt>
<dd>Allow direct I/O access.</dd>
<dt>CAP_MOUNT</dt>
<dd>Allow mounting a file system.</dd>
<dt>CAP_CHROOT</dt>
<dd>Allow changing a root directory.</dd>
</dl>

<h3>ERRORS</h3>
<dl>
<dt>[ESRCH]</dt>
<dd>The specified <i>task</i> is not a valid task ID.</dd>
<dt>[EFAULT]</dt>
<dd>The address of <i>cap</i> is inaccessible.</dd>
<dt>[EPERM]</dt>
<dd>The caller task does not have CAP_SETPCAP capability.</dd>
</dl>
<br>


<h2 id="thr">Thread</h2>

<h3 id="thr0">NAME</h3>
thread_create() - create a new thread

<h3>SYNOPSIS</h3>
<pre>
int thread_create(task_t task, thread_t *th);
</pre>

<h3>DESCRIPTION</h3>
The thread_create() function creates a new thread within <i>task</i>.
The new thread will start at the return address of the thread_create() call.
<br><br>
Since the created thread is initially set to the suspended state,
thread_resume() must be called to start it.

<h3>ERRORS</h3>
<dl>
<dt>[ESRCH]</dt>
<dd>The specified <i>task</i> is not a valid task ID.</dd>
<dt>[EFAULT]</dt>
<dd>The address of <i>th</i> is inaccessible.</dd>
<dt>[ENOMEM]</dt>
<dd>The system is unable to allocate resources.</dd>
<dt>[EPERM]</dt>
<dd>The specified <i>task</i> is not a current task, but the caller
task does not have CAP_TASK capability.</dd>
</dl>
<br>
<hr size="1">


<h3 id="thr1">NAME</h3>
thread_terminate() - terminate a thread

<h3>SYNOPSIS</h3>
<pre>
int thread_terminate(thread_t th);
</pre>

<h3>DESCRIPTION</h3>
The thread_terminate() function terminates a thread.
It will release all resources used by the target thread.
<br><br>
If specified <i>th</i> is the current thread, this routine never returns.

<h3>ERRORS</h3>
<dl>
<dt>[ESRCH]</dt>
<dd>The specified thread <i>th</i> is not a valid thread ID.</dd>
<dt>[EPERM]</dt>
<dd>The caller task is not an owner of the specified <i>th</i>, but the caller
task does not have CAP_TASK capability.</dd>
</dl>
<br>
<hr size="1">


<h3 id="thr2">NAME</h3>
thread_load() - load the thread state

<h3>SYNOPSIS</h3>
<pre>
int thread_load(thread_t th, void *entry, void *stack);
</pre>

<h3>DESCRIPTION</h3>
The thread_load() function loads the thread state (program counter and
stack pointer).
<br><br>
The <i>entry</i> or <i>stack</i> argument can be set to NULL. In this
case, the previous state is used.

<h3>ERRORS</h3>
<dl>
<dt>[ESRCH]</dt>
<dd>The specified <i>th</i> is not a valid thread ID.</dd>
<dt>[EINVAL]</dt>
<dd><i>entry</i> or <i>stack</i> is not a valid address.</dd>
<dt>[EPERM]</dt>
<dd>The caller task is not an owner of the specified <i>th</i>, but the caller
task does not have CAP_TASK capability.</dd>
</dl>
<br>
<hr size="1">


<h3 id="thr3">NAME</h3>
thread_self() - return thread ID

<h3>SYNOPSIS</h3>
<pre>
thread_t thread_self(void);
</pre>

<h3>DESCRIPTION</h3>
The thread_self() function returns ID of the current thread.

<h3>RETURN VALUE</h3>
Current thread ID.
<br>
<br>
<hr size="1">


<h3 id="thr4">NAME</h3>
thread_yield() - yield the processor

<h3>SYNOPSIS</h3>
<pre>
void thread_yield(void);
</pre>

<h3>DESCRIPTION</h3>
The thread_yield() function forces the current thread to release
the processor.

<h3>ERRORS</h3>
No errors are defined.
<br>
<br>
<hr size="1">


<h3 id="thr5">NAME</h3>
thread_suspend() - suspend a thread

<h3>SYNOPSIS</h3>
<pre>
int thread_suspend(thread_t th);
</pre>

<h3>DESCRIPTION</h3>
The thread_suspend() function suspends the specified thread.
Although a thread can be suspended any number of times,
it does not start to run unless it is resumed by the same
number of suspend.

<h3>ERRORS</h3>
<dl>
<dt>[ESRCH]</dt>
<dd>The specified <i>th</i> is not a valid thread ID.</dd>
<dt>[EPERM]</dt>
<dd>The caller task is not an owner of the specified <i>th</i>, but the caller
task does not have CAP_TASK capability.</dd>
</dl>
<br>
<hr size="1">


<h3 id="thr6">NAME</h3>
thread_resume() - resume a thread

<h3>SYNOPSIS</h3>
<pre>
int thread_resume(thread_t th);
</pre>

<h3>DESCRIPTION</h3>
The thread_resume() function resumes the specified thread.
A thread does not begin to run, unless both a thread suspend
count and a task suspend count are set to 0.

<h3>ERRORS</h3>
<dl>
<dt>[ESRCH]</dt>
<dd>The specified <i>th</i> is not a valid thread ID.</dd>
<dt>[EINVAL]</dt>
<dd>The specified <i>th</i> is not suspended now.</dd>
<dt>[EPERM]</dt>
<dd>The caller task is not an owner of the specified <i>th</i>, but the caller
task does not have CAP_TASK capability.</dd>
</dl>
<br>
<hr size="1">


<h3 id="thr7">NAME</h3>
thread_schedparam() - get/set scheduling parameters

<h3>SYNOPSIS</h3>
<pre>
int thread_schedparam(thread_t th, int op, int *param);
</pre>

<h3>DESCRIPTION</h3>
The thread_schedparam() function gets/sets the various scheduling parameter.
<i>op</i> argument is an operation ID which is one of the following value.
<ul>
<li>OP_GETPRIO - get the scheduling priority</li>
<li>OP_SETPRIO - set the scheduling priority</li>
<li>OP_GETPOLICY - get the scheduling policy</li>
<li>OP_SETPOLICY - set the scheduling policy</li>
</ul>
The kernel supports the following scheduling policy.
<ul>
<li>SCHED_FIFO - First-in First-out</li>
<li>SCHED_RR   - Round Robin</li>
</ul>

<h3>ERRORS</h3>
<dl>
<dt>[ESRCH]</dt>
<dd>The specified <i>th</i> is not a valid thread ID.</dd>
<dt>[EFAULT]</dt>
<dd>The address of <i>param</i> is inaccessible.</dd>
<dt>[EINVAL]</dt>
<dd>The kernel does not support the specified policy.</dd>
<dt>[EPERM]</dt>
<dd>The caller task is not an owner of the specified <i>th</i>, or the caller
task does not have CAP_NICE capability to change the parameter.</dd>
</dl>
<br>



<h2 id="vm">Virtual Memory</h2>

<h3 id="vm0">NAME</h3>
vm_allocate() - allocate memory

<h3>SYNOPSIS</h3>
<pre>
int vm_allocate(task_t task, void **addr, size_t size, int anywhere);
</pre>

<h3>DESCRIPTION</h3>
The vm_allocate() function allocates a zero-filled memory in the <i>task</i>'s
memory space.
If the <i>anywhere</i> option is false, the kernel try to allocate the
memory to the address specified by <i>addr</i>. If <i>addr</i> is not
aligned to the page boundary, it will be automatically round down to one.
<i>size</i> argument is an allocation size in byte. It will also be adjusted
to the page boundary.

<h3>ERRORS</h3>
<dl>
<dt>[ESRCH]</dt>
<dd>The specified <i>task</i> is not a valid task ID.</dd>
<dt>[EACCESS]</dt>
<dd>The task is not allowed to allocate the memory to the specified address.</dd>
<dt>[EFAULT]</dt>
<dd>The address of <i>addr</i> is inaccessible.</dd>
<dt>[ENOMEM]</dt>
<dd>Not enough space.</dd>
<dt>[EINVAL]</dt>
<dd>The specified location is already allocated.</dd>
<dt>[EPERM]</dt>
<dd>The specified <i>task</i> is not a current task, but the caller
task does not have CAP_MEMORY capability.</dd>
</dl>
<hr size="1">


<h3 id="vm1">NAME</h3>
vm_free() - free memory

<h3>SYNOPSIS</h3>
<pre>
int vm_free(task_t task, void *addr);
</pre>

<h3>DESCRIPTION</h3>
The vm_free() function deallocates the memory region.
The <i>addr</i> argument must point to the memory region previously
allocated by vm_allocate() or vm_map().

<h3>ERRORS</h3>
<dl>
<dt>[ESRCH]</dt>
<dd>The specified <i>task</i> is not a valid task ID.</dd>
<dt>[EFAULT]</dt>
<dd>The address of <i>addr</i> is inaccessible.</dd>
<dt>[EINVAL]</dt>
<dd>The specified location is not allocated.</dd>
<dt>[EPERM]</dt>
<dd>The specified <i>task</i> is not a current task, but the caller
task does not have CAP_MEMORY capability.</dd>
</dl>
<hr size="1">


<h3 id="vm2">NAME</h3>
vm_attribute() - change memory attribute

<h3>SYNOPSIS</h3>
<pre>
int vm_attribute(task_t task, void *addr, int attr);
</pre>

<h3>DESCRIPTION</h3>
The vm_attribute() function changes the memory attribute.
The <i>addr</i> argument must point to the memory region previously
allocated by vm_allocate() or vm_map().
The attribute type can be chosen a combination of
ATTR_READ, ATTR_WRITE.
Note: ATTR_EXEC is not supported, yet.

<h3>ERRORS</h3>
<dl>
<dt>[ESRCH]</dt>
<dd>The specified <i>task</i> is not a valid task ID.</dd>
<dt>[EFAULT]</dt>
<dd>The address of <i>addr</i> is inaccessible.</dd>
<dt>[EINVAL]</dt>
<dd>The specified location is not allocated. Or, the kernel does not
support the specified attribute.</dd>
<dt>[EPERM]</dt>
<dd>The specified <i>task</i> is not a current task, but the caller
task does not have CAP_MEMORY capability.</dd>
</dl>
<hr size="1">


<h3 id="vm3">NAME</h3>
vm_map() - map memory

<h3>SYNOPSIS</h3>
<pre>
int vm_map(task_t task, void  *addr, size_t size, void **alloc);
</pre>

<h3>DESCRIPTION</h3>
The vm_map() function maps another task's memory to the current
task.
The <i>task</i> argument is the memory owner to map. The memory is
automatically mapped to the free area of current task. The mapped
address is stored in <i>alloc</i> on success.

<h3>ERRORS</h3>
<dl>
<dt>[ESRCH]</dt>
<dd>The specified <i>task</i> is not a valid task ID.</dd>
<dt>[EFAULT]</dt>
<dd>The address of <i>addr</i> or <i>alloc</i> is inaccessible.</dd>
<dt>[EINVAL]</dt>
<dd>The specified location is not allocated.</dd>
<dt>[ENOMEM]</dt>
<dd>Not enough space.</dd>
<dt>[EPERM]</dt>
<dd>The specified <i>task</i> is not a current task, but the caller
task does not have CAP_MEMORY capability.</dd>
</dl>
<br>

<h2 id="tmr">Timer</h2>


<h3 id="tmr0">NAME</h3>
timer_sleep() - sleep for a while

<h3>SYNOPSIS</h3>
<pre>
int timer_sleep(u_long delay, u_long *remain);
</pre>

<h3>DESCRIPTION</h3>
The timer_sleep() function stops execution of the current thread
until specified time passed.
The <i>delay</i> argument is the delay time in milli second.
If this function is canceled by some reason, the remaining time
is stored in <i>remain</i>.

<h3>ERRORS</h3>
<dl>
<dt>[EFAULT]</dt>
<dd>The address of <i>remain</i> is inaccessible.</dd>
<dt>[EINTR]</dt>
<dd>The function was interrupted by an exception.</dd>
</dl>
<br>
<hr size="1">


<h3 id="tmr1">NAME</h3>
timer_alarm() - schedule an alarm exception

<h3>SYNOPSIS</h3>
<pre>
int timer_alarm(u_long delay, u_long *remain);
</pre>

<h3>DESCRIPTION</h3>
The timer_alarm() function sends EXC_ALRM exception to the caller task
after the specified <i>delay</i> milli seconds is passed.
If <i>delay</i> is 0, it stops the alarm timer. When the previous alarm
timer is already working, the remaining time is stored in <i>remain</i>.

<h3>ERRORS</h3>
<dl>
<dt>[EFAULT]</dt>
<dd>The address of <i>remain</i> is inaccessible.</dd>
</dl>
<br>
<hr size="1">


<h3 id="tmr2">NAME</h3>
timer_periodic() - set a periodic timer

<h3>SYNOPSIS</h3>
<pre>
int timer_periodic(thread_t th, u_long start, u_long period);
</pre>

<h3>DESCRIPTION</h3>
The specified thread will be woken up in specified time interval.
The <i>start</i> argument is the first wakeup time. If <i>start</i> is 0,
current periodic timer is stopped. <i>period</i> is the time interval
to wakeup. The unit of <i>start</i>/<i>period</i> is milli seconds.

<h3>ERRORS</h3>
<dl>
<dt>[ESRCH]</dt>
<dd>The specified thread <i>th</i> is not a valid thread ID.</dd>
<dt>[EINVAL]</dt>
<dd><i>start</i> is 0 even when the timer is not started.</dd>
<dt>[ENOMEM]</dt>
<dd>The system is unable to allocate resources.</dd>
<dt>[EPERM]</dt>
<dd>The specified thread <i>th</i> is not in the current task.</dd>
</dl>
<br>
<hr size="1">


<h3 id="tmr3">NAME</h3>
timer_waitperiod() - wait timer period

<h3>SYNOPSIS</h3>
<pre>
int timer_waitperiod(void);
</pre>

<h3>DESCRIPTION</h3>
The timer_waitperiod() function waits the next period of the current
running periodic timer.
<br><br>
Since this routine returns by any exception, the control
may return at non-period time. So, the caller must retry
immediately if the error status is EINTR.

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd>The periodic timer is not started for current thread.</dd>
<dt>[EINTR]</dt>
<dd>The function was interrupted by an exception.</dd>
</dl>
<br>



<h2 id="ex">Exception</h2>

<h3 id="ex0">NAME</h3>
exception_setup() - setup exception handler

<h3>SYNOPSIS</h3>
<pre>
int exception_setup(void (*handler)(int, void *));
</pre>

<h3>DESCRIPTION</h3>
Setup an exception handler for the current task.
NULL can be specified as <i>handler</i> to remove current handler.
If the handler is removed, all pending exceptions are discarded
and all exception_wait() are canceled.
Only one exception handler can be set per task. If the previous
handler exists in task, exception_setup() just overwrite the handler.
<br><br>
The exception handler must have the following arguments.<br>
<br>
void exception_handler(int excpt, void *regs);<br>
<br>
<i>excpt</i> is an exception number, and <i>regs</i> are the machine
dependent registers. The exception handler must call the exception_return()
function after it processes the exception.

<h3>ERRORS</h3>
<dl>
<dt>[EFAULT]</dt>
<dd>The address of <i>handler</i> is inaccessible.</dd>
</dl>
<br>
<hr size="1">


<h3 id="ex1">NAME</h3>
exception_return() - return from exception handler

<h3>SYNOPSIS</h3>
<pre>
int exception_return(void *regs);
</pre>

<h3>DESCRIPTION</h3>
The exception_return() function is used to return from the exception
handler. <i>regs</i> argument must be the same value which is passed
to the handler.

<h3>ERRORS</h3>
<dl>
<dt>[EFAULT]</dt>
<dd>The address of <i>regs</i> is inaccessible.</dd>
</dl>
<br>
<hr size="1">


<h3 id="ex2">NAME</h3>
exception_raise() - raise an exception

<h3>SYNOPSIS</h3>
<pre>
int exception_raise(task_t task, int excpt);
</pre>

<h3>DESCRIPTION</h3>
The exception_raise() function raises an exception for the specified task.

<h3>ERRORS</h3>
<dl>
<dt>[ESRCH]</dt>
<dd>The specified <i>task</i> is not a valid task ID.</dd>
<dt>[EINVAL]</dt>
<dd>The specified <i>excpt</i> is not a valid exception.</dd>
<dt>[EPERM]</dt>
<dd><i>task</i> is a kernel task, or the task does not register an
exception handler.
<dt>[EPERM]</dt>
<dd>The specified <i>task</i> is not a current task, but the caller
task does not have CAP_KILL capability.</dd>
</dl>
<br>
<hr size="1">


<h3 id="ex3">NAME</h3>
exception_wait() - wait an exception

<h3>SYNOPSIS</h3>
<pre>
int exception_wait(int *excpt);
</pre>

<h3>DESCRIPTION</h3>
The exception_wait() function blocks the caller thread until
any exception is raised to the thread.
<br><br>
This routine returns EINTR on success.

<h3>ERRORS</h3>
<dl>
<dt>[EFAULT]</dt>
<dd>The address of <i>excpt</i> is inaccessible.</dd>
<dt>[EINVAL]</dt>
<dd>The caller thread does not register an exception handler.</dd>
</dl>
<br>


<h2 id="dev">Device</h2>

<h3 id="dev0">NAME</h3>
device_open() - open a device

<h3>SYNOPSIS</h3>
<pre>
int device_open(const char *name, int mode, device_t *dev);
</pre>

<h3>DESCRIPTION</h3>
The device_open() function opens the specified device.
<i>mode</i> is one of the following open mode.
<ul>
<li>O_RDONLY - Read only</li>
<li>O_WRONLY - Write only</li>
<li>O_RDWR - Read & Write</li>
</ul>
The ID of the opened device is stored in <i>dev</i> on success.

<h3>ERRORS</h3>
<dl>
<dt>[EFAULT]</dt>
<dd>The address of <i>name</i> is inaccessible.</dd>
<dt>[ENAMETOOLONG]</dt>
<dd>The length of the <i>name</i> argument exceeds MAX_DEVNAME.</dd>
<dt>[ENOENT]</dt>
<dd>The length of the <i>name</i> argument is 0.</dd>
<dt>[ENXIO]</dt>
<dd>The device was not found.</dd>
<dt>[EPERM]</dt>
<dd>The caller task does not have CAP_DEVIO capability.</dd>
</dl>
Other device specific error may be returned.
<br><br>
<hr size="1">


<h3 id="dev1">NAME</h3>
device_close() - close a device

<h3>SYNOPSIS</h3>
<pre>
int device_close(device_t dev);
</pre>

<h3>DESCRIPTION</h3>
The device_close() function close the specified device.

<h3>ERRORS</h3>
<dl>
<dt>[ENODEV]</dt>
<dd>The specified device is not valid device.</dd>
<dt>[EBADF]</dt>
<dd>The specified device is not a valid device opened.</dd>
<dt>[EPERM]</dt>
<dd>The caller task does not have CAP_DEVIO capability.</dd>
</dl>
Other device specific error may be returned.
<br><br>
<hr size="1">


<h3 id="dev2">NAME</h3>
device_read() - read from a device

<h3>SYNOPSIS</h3>
<pre>
int device_read(device_t dev, void *buf, size_t *nbyte, int blkno);
</pre>

<h3>DESCRIPTION</h3>
The device_read() function reads data from the specified device.
<i>nbyte</i> is a read size in byte, and <i>blkno</i> is a start block
of the target device. The unit of <i>blkno</i> is device specific.

<h3>ERRORS</h3>
<dl>
<dt>[ENODEV]</dt>
<dd>The specified device is not valid device.</dd>
<dt>[EBADF]</dt>
<dd>The specified device is not a valid device opened for read.</dd>
<dt>[EFAULT]</dt>
<dd>The specified buffer is inaccessible, or not writable.</dd>
<dt>[EPERM]</dt>
<dd>The caller task does not have CAP_DEVIO capability.</dd>
</dl>
Other device specific error may be returned.
<br><br>
<hr size="1">


<h3 id="dev3">NAME</h3>
device_write() - write to a device

<h3>SYNOPSIS</h3>
<pre>
int device_write(device_t dev, void *buf, size_t *nbyte, int blkno);
</pre>

<h3>DESCRIPTION</h3>
The device_read() function writes data to the specified device.
<i>nbytes</i> is a write size in byte, and <i>blkno</i> is a start block
of the target device. The unit of <i>blkno</i> is device specific.

<h3>ERRORS</h3>
<dl>
<dt>[ENODEV]</dt>
<dd>The specified device is not valid device.</dd>
<dt>[EBADF]</dt>
<dd>The specified device is not a valid device opened for write.</dd>
<dt>[EFAULT]</dt>
<dd>The specified buffer is inaccessible</dd>
<dt>[EPERM]</dt>
<dd>The caller task does not have CAP_DEVIO capability.</dd>
</dl>
Other device specific error may be returned.
<br><br>
<hr size="1">


<h3 id="dev4">NAME</h3>
device_ioctl() - control a device

<h3>SYNOPSIS</h3>
<pre>
int device_ioctl(device_t dev, int cmd, u_long arg);
</pre>

<h3>DESCRIPTION</h3>
The device_ioctl() function sends a command to the specified device.
<i>cmd</i> and <i>arg</i> are device dependent.

<h3>ERRORS</h3>
<dl>
<dt>[ENODEV]</dt>
<dd>The specified device is not valid device.</dd>
<dt>[EBADF]</dt>
<dd>The specified device is not a valid device opened for ioctl.</dd>
<dt>[EPERM]</dt>
<dd>The caller task does not have CAP_DEVIO capability.</dd>
</dl>
<br>



<h2 id="mu">Mutex</h2>

<h3 id="mu0">NAME</h3>
mutex_init() - initialize a mutex

<h3>SYNOPSIS</h3>
<pre>
int mutex_init(mutex_t *mu);
</pre>

<h3>DESCRIPTION</h3>
The mutex_init() function creates a new mutex and initializes it.
The ID of the new mutex is stored in <i>mu</i> on success.
<br><br>
If an initialized mutex is reinitialized, undefined behavior results.

<h3>ERRORS</h3>
<dl>
<dt>[ENOMEM]</dt>
<dd>The system is unable to allocate resources.</dd>
<dt>[EFAULT]</dt>
<dd>The address of <i>mu</i> is inaccessible.</dd>
</dl>
<br>
<hr size="1">


<h3 id="mu1">NAME</h3>
mutex_destroy() - destroy a mutex

<h3>SYNOPSIS</h3>
<pre>
int mutex_destroy(mutex_t *mu);
</pre>

<h3>DESCRIPTION</h3>
The mutex_destroy() function destroys the specified mutex.
The mutex must be unlock state, otherwise it fails with EBUSY.

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd>The specified mutex is not a valid mutex.</dd>
<dt>[EBUSY]</dt>
<dd>The mutex is still locked by some thread.</dd>
</dl>
<br>
<hr size="1">


<h3 id="mu2">NAME</h3>
mutex_trylock() - try to lock a mutex

<h3>SYNOPSIS</h3>
<pre>
int mutex_trylock(mutex_t *mu);
</pre>

<h3>DESCRIPTION</h3>
The mutex_trylock() tries to lock a mutex without blocking.

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd>The specified mutex is not a valid mutex.</dd>
<dt>[EBUSY]</dt>
<dd>The mutex is already locked.</dd>
</dl>
<br>
<hr size="1">


<h3 id="mu3">NAME</h3>
mutex_lock() - lock a mutex

<h3>SYNOPSIS</h3>
<pre>
int mutex_lock(mutex_t *mu);
</pre>

<h3>DESCRIPTION</h3>
The mutex_lock() locks the specified mutex.
The caller thread is blocked if the mutex has already been locked.
If the caller thread receives any exception while waiting a mutex,
this routine returns with EINTR.
The mutex is "recursive". It means a thread can lock the same mutex
any number of times.
<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd>The specified mutex is not a valid mutex.</dd>
<dt>[EINTR]</dt>
<dd>The function was interrupted by an exception.</dd>
</dl>
<br>
<hr size="1">


<h3 id="mu4">NAME</h3>
mutex_unlock() - unlock a mutex

<h3>SYNOPSIS</h3>
<pre>
int mutex_unlock(mutex_t *mu);
</pre>

<h3>DESCRIPTION</h3>
The mutex_unlock() function unlocks the specified mutex.
The caller thread must be the current mutex owner.

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd>The specified mutex is not a valid mutex.</dd>
<dt>[EPERM]</dt>
<dd>The caller thread is not the mutex owner.</dd>
</dl>
<br>



<h2 id="cv">Condition Variable</h2>

<h3 id="cv0">NAME</h3>
cond_init() - initialize a condition variable

<h3>SYNOPSIS</h3>
<pre>
int cond_init(cond_t *cond);
</pre>

<h3>DESCRIPTION</h3>
The cond_init() function creates a new condition variable and initializes it.
<br><br>
If an initialized condition variable is reinitialized, undefined behavior results.

<h3>ERRORS</h3>
<dl>
<dt>[EFAULT]</dt>
<dd>The address of <i>cond</i> is inaccessible.</dd>
<dt>[ENOMEM]</dt>
<dd>The system is unable to allocate resources.</dd>
</dl>
<br>
<hr size="1">


<h3 id="cv1">NAME</h3>
cond_destroy() - destroy a condition variable

<h3>SYNOPSIS</h3>
<pre>
int cond_destroy(cond_t *cond);
</pre>

<h3>DESCRIPTION</h3>
The cond_destroy() function destroys the specified condition variable.
If there are any blocked thread waiting for the specified CV, it
returns EBUSY.

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd>The specified condition variable is not valid.</dd>
<dt>[EBUSY]</dt>
<dd>The condition variable is still locked by some thread.</dd>
</dl>
<br>
<hr size="1">


<h3 id="cv2">NAME</h3>
cond_wait() - wait on a condition

<h3>SYNOPSIS</h3>
<pre>
int cond_wait(cond_t *cond, mutex_t *mu);
</pre>

<h3>DESCRIPTION</h3>
The cond_wait() function waits on the specified condition.
If the caller thread receives any exception, this routine returns
with EINTR.

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd>The specified condition variable is not valid.</dd>
<dt>[EINTR]</dt>
<dd>The function was interrupted by an exception.</dd>
</dl>
<br>
<hr size="1">


<h3 id="cv3">NAME</h3>
cond_signal() - signal condition

<h3>SYNOPSIS</h3>
<pre>
int cond_signal(cond_t *cond);
</pre>

<h3>DESCRIPTION</h3>
The cond_signal() function unblocks the thread that is waiting
on the specified condition variable.

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd>The specified condition variable is not valid.</dd>
</dl>
<br>
<hr size="1">


<h3 id="cv4">NAME</h3>
cond_broadcast() - broadcast a condition

<h3>SYNOPSIS</h3>
<pre>
int cond_broadcast(cond_t *cond);
</pre>

<h3>DESCRIPTION</h3>
The cond_broadcast() function unblocks all threads that are blocked
on the specified condition variable.

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd>The specified condition variable is not valid.</dd>
</dl>
<br>



<h2 id="sem">Semaphore</h2>

<h3 id="sem0">NAME</h3>
sem_init() - initialize a semaphore

<h3>SYNOPSIS</h3>
<pre>
int sem_init(sem_t *sem, u_int value);
</pre>

<h3>DESCRIPTION</h3>
The sem_init() function initializes a semaphore. It will create a
new semaphore if the specified <i>sem</i> does not exist. If the
specified semaphore <i>sem</i> already exists, it is re-initialized
only if nobody is waiting for it.
The initial semaphore value is set to <i>value</i> value.
The ID of the new semaphore is stored in <i>sem</i> on success.

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd><i>value</i> value is larger than SEM_MAX.</dd>
<dt>[ENOSPC]</dt>
<dd>The system is unable to allocate resources.</dd>
<dt>[EFAULT]</dt>
<dd>The address of <i>sem</i> is inaccessible.</dd>
<dt>[EBUSY]</dt>
<dd>There are currently threads blocked on the semaphore.</dd>
<dt>[EPERM]</dt>
<dd>The caller task is not an owner of the <i>sem</i>, but it
does not have CAP_SEMAPHORE capability.</dd>
</dl>
<br>
<hr size="1">


<h3 id="sem1">NAME</h3>
sem_destroy() - destroy a semaphore

<h3>SYNOPSIS</h3>
<pre>
int sem_destroy(sem_t *sem);
</pre>

<h3>DESCRIPTION</h3>
The sem_destroy() function destroys the specified semaphore.
If some thread is waiting for the specified semaphore, this routine
fails with EBUSY.

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd>The specified semaphore is not a valid semaphore.</dd>
<dt>[EBUSY]</dt>
<dd>There are currently threads blocked on the semaphore.</dd>
</dl>
<br>
<hr size="1">


<h3 id="sem2">NAME</h3>
sem_wait() - lock a semaphore

<h3>SYNOPSIS</h3>
<pre>
int sem_wait(sem_t *sem, u_long timeout);
</pre>

<h3>DESCRIPTION</h3>
The sem_wait() function locks the semaphore referred by <i>sem</i>
only if the semaphore value is currently positive. The thread
will sleep while the semaphore value is zero.
It decrements the semaphore value in return.
If <i>timeout</i> value is set if it is not 0.

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd>The specified semaphore is not a valid semaphore.</dd>
<dt>[ETIMEDOUT]</dt>
<dd>Time out.</dd>
<dt>[EINTR]</dt>
<dd>The function was interrupted by an exception.</dd>
<dt>[EPERM]</dt>
<dd>The caller task is not an owner of the <i>sem</i>, but it
does not have CAP_SEMAPHORE capability.</dd>
</dl>
<br>
<hr size="1">


<h3 id="sem3">NAME</h3>
sem_trywait() - try to lock a semaphore

<h3>SYNOPSIS</h3>
<pre>
int sem_trywait(sem_t *sem);
</pre>

<h3>DESCRIPTION</h3>
The sem_trylock() tries to lock a semaphore without blocking.

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd>The specified semaphore is not a valid semaphore.</dd>
<dt>[EAGAIN]</dt>
<dd>The semaphore is already locked.</dd>
<dt>[EPERM]</dt>
<dd>The caller task is not an owner of the <i>sem</i>, but it
does not have CAP_SEMAPHORE capability.</dd>
</dl>
<br>
<hr size="1">


<h3 id="sem4">NAME</h3>
sem_post() - unlock a semaphore

<h3>SYNOPSIS</h3>
<pre>
int sem_post(sem_t *sem);
</pre>

<h3>DESCRIPTION</h3>
The sem_post() function unlock the specified semaphore.
It increments the semaphore value.
If the semaphore value becomes positive, one of the threads waiting
to lock will be unblocked.
The caller thread is not blocked by this function.

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd>The specified semaphore is not a valid semaphore.</dd>
<dt>[ERANGE]</dt>
<dd>The semaphore value exceeds SEM_MAX.</dd>
<dt>[EPERM]</dt>
<dd>The caller task is not an owner of the <i>sem</i>, but it
does not have CAP_SEMAPHORE capability.</dd>
</dl>
<br>
<hr size="1">


<h3 id="sem5">NAME</h3>
sem_getvalue() - get the value of a semaphore

<h3>SYNOPSIS</h3>
<pre>
int sem_getvalue(sem_t *sem, u_int *value);
</pre>

<h3>DESCRIPTION</h3>
The sem_getvalue() function returns the current value of the specified semaphore.

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd>The specified semaphore is not a valid semaphore.</dd>
<dt>[EFAULT]</dt>
<dd>The address of <i>sem</i> is inaccessible.</dd>
<dt>[EPERM]</dt>
<dd>The caller task is not an owner of the <i>sem</i>, but it
does not have CAP_SEMAPHORE capability.</dd>
</dl>
<br>



<h2 id="sys">System</h2>

<h3 id="sys0">NAME</h3>
sys_log() - log a message

<h3>SYNOPSIS</h3>
<pre>
void sys_log(const char *buf);
</pre>

<h3>DESCRIPTION</h3>
The sys_log() function puts the specified text message to the
predefined device.
This function is available only when the kernel is built with debug flag.

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd>The message is too long.</dd>
<dt>[EFAULT]</dt>
<dd>The address of <i>buf</i> is inaccessible.</dd>
</dl>
<br>
<hr size="1">


<h3 id="sys1">NAME</h3>
sys_panic() - fatal error

<h3>SYNOPSIS</h3>
<pre>
void sys_panic(const char *buf);
</pre>

<h3>DESCRIPTION</h3>
The sys_panic() function shows the panic message and stops the system.
The application should use this call only when it detects the unrecoverable
error.

<h3>ERRORS</h3>
No errors are defined.
<br>
<br>
<hr size="1">



<h3 id="sys2">NAME</h3>
sys_info() - return system information

<h3>SYNOPSIS</h3>
<pre>
int sys_info(int type, void *buf);
</pre>

<h3>DESCRIPTION</h3>
The sys_info() function returns the specified system information.
The kernel supports the following system infomation.
<ul>
<li>INFO_KERNEL - Get kernel information</li>
<li>INFO_MEMORY - Get memory information</li>
<li>INFO_SCHED - Get scheduling information</li>
<li>INFO_THREAD - Get thread information</li>
<li>INFO_DEVICE - Get device information</li>
</ul>

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd><i>type</i> is not a valid type.</dd>
<dt>[EFAULT]</dt>
<dd>The address of <i>buf</i> is inaccessible.</dd>
</dl>
<br>
<hr size="1">



<h3 id="sys3">NAME</h3>
sys_time() - return system ticks

<h3>SYNOPSIS</h3>
<pre>
int sys_time(u_long *ticks);
</pre>

<h3>DESCRIPTION</h3>
The sys_time() function returns the current system ticks.

<h3>ERRORS</h3>
<dl>
<dt>[EFAULT]</dt>
<dd>The address of <i>ticks</i> is inaccessible.</dd>
</dl>
<br>
<hr size="1">



<h3 id="sys4">NAME</h3>
sys_debug() - kernel debugging interface

<h3>SYNOPSIS</h3>
<pre>
int sys_debug(int cmd, int param);
</pre>

<h3>DESCRIPTION</h3>
The sys_debug() controls the kernel built-in debug functions.
The kernel supports the following commands.
<ul>
<li>DBGCMD_DUMP - Dump kernel information</li>
</ul>

<h3>ERRORS</h3>
<dl>
<dt>[EINVAL]</dt>
<dd><i>cmd</i> is not a valid command.</dd>
<dt>[ENOSYS]</dt>
<dd>The function is not supported.</dd>
</dl>
<br>

      </td>
    </tr>
    <tr>
      <td id="footer" colspan="2" style="vertical-align: top;">
        <a href="http://sourceforge.net">
        <img src="http://sourceforge.net/sflogo.php?group_id=132028&amp;type=1"
        alt="SourceForge.net Logo" border="0" height="31" width="88"></a><br>
        Copyright&copy; 2005-2007 Kohsuke Ohtani
      </td>
    </tr>

  </tbody>
</table>

</div>
<div id="bottom"></div>

</body>
</html>