Files
MiniGUI/include/psos.h
2020-02-02 10:53:31 +08:00

921 lines
40 KiB
C
Raw Permalink Blame History

///////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT NOTICE
//
// The following open source license statement does not apply to any
// entity in the Exception List published by FMSoft.
//
// For more information, please visit:
//
// https://www.fmsoft.cn/exception-list
//
//////////////////////////////////////////////////////////////////////////////
/**
* \file psos.h
* \author Wei Yongming <vincent@minigui.org>
* \date 2007/05/28
*
* \brief This header contains the declaration of pSOS+ system calls, the definition
* of related structures, and the error codes.
*
\verbatim
This file is part of MiniGUI, a mature cross-platform windowing
and Graphics User Interface (GUI) support system for embedded systems
and smart IoT devices.
Copyright (C) 2008~2020, Beijing FMSoft Technologies Co., Ltd.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Or,
As this program is a library, any link to this program must follow
GNU General Public License version 3 (GPLv3). If you cannot accept
GPLv3, you need to be licensed from FMSoft.
If you have got a commercial license of this program, please use it
under the terms and conditions of the commercial license.
For more information about the commercial license, please refer to
<http://www.minigui.com/blog/minigui-licensing-policy/>.
\endverbatim
*/
/*
* $Id: psos.h 7183 2007-05-16 08:19:34Z weiym $
*
* MiniGUI for Linux/uClinux, eCos, uC/OS-II, VxWorks,
* pSOS, ThreadX, NuCleus, OSE, and Win32.
*/
#ifndef _PSOS_H
#define _PSOS_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Timed out; returned only if a timeout was requested. */
#define ERR_TIMEOUT 0x01
/* Illegal system service function number. */
#define ERR_SSFN 0x03
/* Node specifier out of range. */
#define ERR_NODENO 0x04
/* object has been deleted. */
#define ERR_OBJDEL 0x05
/* object_id is incorrect; failed validity check */
#define ERR_OBJID 0x06
/* object type doesn't match object ID; failed validity check.*/
#define ERR_OBJTYPE 0x07
/* Node's object table full. */
#define ERR_OBJTFULL 0x08
/* Named object not found. */
#define ERR_OBJNF 0x09
/* Informative; files may be corrupted on restart. */
#define ERR_RSTFS 0x0D
/* Exceeds node's maximum number of tasks. */
#define ERR_NOTCB 0x0E
/* Insufficient space in Region 0 to create stack. */
#define ERR_NOSTK 0x0F
/* Stack too small. */
#define ERR_TINYSTK 0x10
/* Priority out of range. For mu, the MU_PRIO_PROTECT flag has been specified.
* The priority must be more than 0 and less than 256. */
#define ERR_PRIOR 0x11
/* Task already started. */
#define ERR_ACTIVE 0x12
/* Cannot restart; this task never was started. */
#define ERR_NACTIVE 0x13
/* Task already suspended. */
#define ERR_SUSP 0x14
/* The task was not suspended. */
#define ERR_NOTSUSP 0x15
/* Cannot change priority; new priority out of range. */
#define ERR_SETPRI 0x16
/* Register number out of range. */
#define ERR_REGNUM 0x17
/* pHILE+ resources in use. */
#define ERR_DELFS 0x18
/* pREPC+ resources in use. */
#define ERR_DELLC 0x19
/* pNA+ resources in use. */
#define ERR_DELNS 0x1A
/* error cods for region manager are omitted ... */
/* error cods for partition manager are omitted ... */
/* Could not send a notification event. Error occurred while sending notification of message availability. */
#define ERR_NOTIFY 0x3D
/* Exceeds node's maximum number of semaphores. */
#define ERR_NOSCB 0x41
/* No semaphore: this error code returns only if SM_NOWAIT was selected. */
#define ERR_NOSEM 0x42
/* Semaphore deleted while task waiting. */
#define ERR_SKILLD 0x43
/* Informative only; there were sm_delete tasks waiting. */
#define ERR_TATSDEL 0x44
/* Maximum number of tokens are already available for a semaphore that was created with the SM_BOUNDED flag. */
#define ERR_BOUND 0x45
/* ZERO bound count is invalid. */
#define ERR_INVBOUND 0x46
/* error cods for timer are omitted ... */
/* object not created from this node. */
#define ERR_ILLRSC 0x53
/* Cannot wait; the remote node is out of Agents. */
#define ERR_NOAGNT 0x54
/* object does not exist any more. */
#define ERR_STALEID 0x65
/* Remote node is no longer in service. */
#define ERR_NDKLD 0x66
/* Exceeds node's maximum number of mutexes. */
#define ERR_NOMUCB 0x70
/* The MU_GLOBAL flag cannot be specified with the MU_PRIO_INHERIT flag. */
#define ERR_NOGLOBAL 0x71
/* Informative only: there were tasks waiting. */
#define ERR_TATMUDEL 0x72
/* The mutex is not owned by the calling task. */
#define ERR_NOTOWNED 0x73
/* The mutex is already locked by the calling task and it was created with MU_NORECURSIVE flag. */
#define ERR_NORECURSIVE 0x74
/* Some other task has already locked the mutex; this error is returned only if MU_NOWAIT flag has been specified. */
#define ERR_MULOCKED 0x75
/* Mutex deleted while the task was waiting on it. */
#define ERR_MUKILLED 0x76
/* MU_FIFO flag cannot be specified with MU_PRIO_INHERIT or MU_PRIO_PROTECT. */
#define ERR_NOFIFO 0x77
/* Task was created with T_NORELMU flag set and currently owns some mutexes. */
#define ERR_OWNMUTX 0x79
/* Task<73><6B>s current priority exceedsthe ceiling priority of the guarding mutex. */
#define ERR_OUTCEIL 0x7A
/* Expected mutex object; failed validity. The mutex is not of priority protected type. */
#define ERR_MUTYPE 0x8A
/* other error cods are omitted ... */
/* system calls for ASR management */
#define T_PREEMPT 0x00000001 /* ASR is preemptible. */
#define T_NOPREEMPT 0x00000002 /* ASR is non-preemptible. */
#define T_TSLICE 0x00000010 /* ASR can be time-sliced. */
#define T_NOTSLICE 0x00000020 /* ASR cannot be time-sliced. */
#define T_ASR 0x00000100 /* ASR nesting enabled. */
#define T_NOASR 0x00000200 /* ASR nesting disabled. */
#define T_USER 0x00001000 /* ASR runs in user mode. */
#define T_SUPV 0x00002000 /* ASR runs in supervisor mode. */
#define T_ISR 0x00010000 /* Interrupts are enabled while ASR runs. */
#define T_NOISR 0x00020000 /* Interrupts are disabled while ASR runs. */
/*
* This system call allows a task to specify an asynchronous signal routine
* (ASR) to handle asynchronous signals. as_catch() supplies the starting
* address of the task's ASR, and its initial execution mode. If the input
* ASR address is zero, then the caller is deemed to have an invalid ASR,
* and any signals sent to it will be rejected.
*
* A task's ASR gains control much like an ISR. If a task has pending signals
* (sent via as_send()), then the next time the task is dispatched to run,
* it will be forced to first execute the task's specified ASR. A task
* executes its ASR according to the mode supplied by the as_catch() call
* (for example, Non-preemptible, Time-slicing enabled, etc.) Upon entry to
* the ASR, all pending signals - including all those received since the
* last ASR invocation - are passed as an argument to the ASR. In addition,
* a stack frame is built to facilitate the return from the ASR.
*
* as_catch() replaces any previous ASR for the calling task. Therefore, a
* task can have only one ASR at any time. An ASR must exit using the
* as_return() system call.
*/
unsigned long as_catch (
void (* start_addr) (unsigned long), /* ASR address */
unsigned long mode /* ASR attributes */
);
/*
* This system call registers a set of bit-encoded events for the calling
* task that are used to notify the posting of asynchronous signals to
* the task. The event notification mechanism provides a way for a task to
* synchronously wait for asynchronous signals via an ev_receive() call.
*/
unsigned long as_notify (
unsigned long events /* bit-encoded events */
);
/*
* This system call must be used by a task's ASR to exit and return to
* the original flow of execution of the task. The purpose of this call is
* to enable the pSOS+ kernel to restore the task to its state before
* the ASR. as_return() cannot be called except from an ASR.
*/
unsigned long as_return (void);
/*
* This system call sends asynchronous signals to a task. Additionally,
* if signal notification via event has been requested, the notification
* events are also posted to the task. The purpose of these signals is to
* force a task to break from its normal flow of execution and execute
* its Asynchronous Signal Routine (ASR).
*
* Asynchronous signals are like software interrupts, with ASRs taking on
* the role of ISRs. Unlike an interrupt, which is serviced almost
* immediately, an asynchronous signal does not immediately affect the
* state of the task. An as_send() call is serviced only when the task is
* next dispatched to run (and that depends on the state of the task and
* its priority).
*
* Each task has 32 signals. These signals are encoded bit-wise in a single
* long word.
*
* Like events, signals are neither queued nor counted. For example, if
* three identical signals are sent to a task before its ASR has a chance
* to execute, the three signals have the same effect as one.
*/
unsigned long as_send (
unsigned long tid, /* target task ID */
unsigned long signals /* bit-encoded signal list */
);
/* system calls for task management */
/*
* This system call adds a task variable to a task. t_addvar() allocates to the specified
* task a storage area which is used to hold a private copy of the specified variable.
*/
unsigned long t_addvar (
unsigned long tid, /* task identifier */
void **tv_addr, /* address of variable */
void *tv_value /* initial value for task variable */
);
#define T_GLOBAL 0x0001
#define T_LOCAL 0x0002
#define T_FPU 0x0010
#define T_NOFPU 0x0020
/*
* This service call enables a task to create a new task. t_create() allocates to the
* new task a Task Control Block (TCB) and a memory segment for its stack(s). The
* task stack sizes and scheduling priority are established with this call. t_create()
* leaves the new task in a dormant state; the t_start() call must be used to place
* the task into the ready state for execution.
*/
unsigned long t_create (
char name[4], /* task name */
unsigned long prio, /* task priority */
unsigned long sstack, /* task supervisor stack size */
unsigned long ustack, /* task user stack size */
unsigned long flags, /* task attributes */
unsigned long *tid /* task identifier */
);
/*
* This service call enables a task to delete itself or another task. The pSOS+ kernel
* first dispatches any task deletion callouts, registered via the co_register() pSOS+
* service, in the reverse order of registration. When all of the deletion callouts have
* finished, the pSOS+ kernel halts the task and reclaims its TCB, stack segment and
* any allocated timers.
* The calling task does not have to be the creator (parent) of the task to be deleted.
* However, a task must be deleted from the node on which it was created.
*/
unsigned long t_delete (
unsigned long tid /* task identifier */
);
/*
* This system call removes a task variable from a task. t_delvar() deallocates the
* private storage allocated for the task variable.
*/
unsigned long t_delvar (
unsigned long tid, /* task identifier */
void **tv_addr /* address of variable*/
);
/*
* This system call enables the caller to obtain the contents of a task's notepad register.
* Each task has 16 such software registers, held in the task's TCB. The purpose
* of these registers is to furnish every task with a set of named, permanent variables.
* Eight of these registers are reserved for system use. Eight are free to be used for application
* specific purposes.
*/
unsigned long t_getreg (
unsigned long tid, /* task identifier */
unsigned long regnum, /* register number */
unsigned long *reg_value /* register contents */
);
/*
* This system call enables the calling task to obtain the task ID of a task it knows only
* by name. This task ID can then be used in all other operations relating to the task.
* Most system calls, except t_create() and t_ident(), reference a task by its task
* ID. t_create() returns the task ID to a task's creator. For other tasks, one way to
* obtain the task ID is to use t_ident().
*/
unsigned long t_ident (
char name[4], /* task name */
unsigned long node, /* node number */
unsigned long *tid /* task ID */
);
#define TS_DEBUG 0x8000 /* Blocked by debugger */
#define TS_SUSP 0x4000 /* Suspended */
#define TS_TIMING 0x1000 /* Being timed */
#define TS_PAUSE 0x0800 /* Task paused */
#define TS_ABSTIME 0x0400 /* Timed for absolute time */
#define TS_VWAIT 0x0200 /* Waiting for events */
#define TS_SWAIT 0x0080 /* Waiting for semaphore */
#define TS_MWAIT 0x0040 /* Waiting for memory */
#define TS_QWAIT 0x0020 /* Waiting for message */
#define TS_RWAIT 0x0010 /* Waiting for reply packet */
#define TS_MUWAIT 0x0008 /* Waiting for mutex */
#define TS_CVWAIT 0x0004 /* Waiting for condition variable */
#define TS_CWAIT 0x0001 /* Waiting for component resource */
#define TS_READY 0x0000 /* Task is in Ready State */
struct tinfo {
char name[4]; /* Task name */
unsigned long flags; /* Task attributes */
void (*iip)(void); /* Task's initial starting addr. */
unsigned long next; /* ID of the next waiting task */
unsigned short status; /* Task status.*/
unsigned char cpriority; /* Task's current priority.*/
unsigned char bpriority; /* Task's base priority */
unsigned char ipriority; /* Task's initial priority */
unsigned char evwantcond; /* Task's event wait condition */
unsigned short mode; /* Task's current mode.*/
unsigned short imode; /* Task's initial mode */
unsigned short amode; /* Task's ASR mode.*/
unsigned long tslice_quantum; /* Per task's time slice in ticks*/
long tslice_remain; /* Remainder time slice in ticks.*/
unsigned long wtobid; /* Object where task is blocked */
unsigned long evwait; /* Events - task waiting for.*/
unsigned long evcaught; /* Events caught */
unsigned long evrcvd; /* Events received */
unsigned long ss_size; /* Supervisor stack size */
unsigned long us_size; /* User stack size */
unsigned long *ssp; /* Current supervisor stack */
/* pointer */
unsigned long *issp; /* Initial supervisor stack pointer */
unsigned long *usp; /* Current user stack pointer */
unsigned long *iusp; /* Initial user stack pointer */
unsigned long imask; /* Interrupt priority level */
void (*asr_addr)(void); /* Task's ASR address */
unsigned long signal; /* Asynchronous signals pending */
unsigned long xdate; /* Timer expiry date */
unsigned long xtime; /* Timer expiry time */
unsigned long xticks; /* Timer expiry ticks */
unsigned long nrnunits; /* No. of region units wanted */
void **tsdp; /* Task_specific_Data pointer */
unsigned long co_toproc; /* Callouts to process */
unsigned long co_inprog; /* Callouts in progress */
unsigned long evasr_ntfy; /* ev used for ASR notification */
};
/*
* This system call returns information of a specified task. The information includes
* the static information that was specified at object creation time and certain internal
* state information which is not static.
*/
unsigned long t_info (
unsigned long tid, /* Task ID */
struct tinfo *buf /* Object Information buffer */
);
#if 0
#define T_PREEMPT 0x0001 /* Task is preemptible. */
#define T_NOPREEMPT 0x0002 /* Task is non-preemptible. */
#define T_TSLICE 0x0004 /* Task can be time-sliced. */
#define T_NOTSLICE 0x0008 /* Task cannot be time-sliced. */
#define T_ASR 0x0010 /* Task's ASR is enabled. */
#define T_NOASR 0x0020 /* Task's ASR is disabled. */
#define T_USER 0X0040 /* Task runs in user mode. */
#define T_SUPV 0x0080 /* Task runs in supervisor mode. */
#define T_ISR 0x0100 /* Hardware interrupts are enabled while the task runs. */
#define T_NOISR 0x0200 /* Hardware interrupts are disabled while the task runs. */
#endif
/*
* This system call enables a task to modify certain execution mode fields. These are
* preemption on/off, roundrobin on/off, asynchronous signal handling on/off, and
* interrupt control.
* Preemption has precedence over timeslicing. Therefore, if preemption is off, timeslicing
* does not occur whether or not it is set.
* The calling task can be preempted as a result of this call, if its preemptibility is
* turned from off to on and a higher priority task is ready to run.
* To obtain a task's current execution mode without changing it, use a mask of 0.
*/
unsigned long t_mode (
unsigned long mask, /* attributes to be changed */
unsigned long new_mode, /* new attributes */
unsigned long *old_mode /* prior mode */
);
/*
* This system call forces a task to resume execution at its original start address regardless
* of its current state or place of execution. If the task was blocked, the
* pSOS+ kernel forcibly unblocks it. The task's priority and stacks are set to the original
* values that t_create() specified. Its start address and execution mode are reset
* to the original values established by t_start(). Any pending events, signals, or
* armed timers are cleared. Thereafter, pSOS+ posts any "task restart callouts" that
* are dispatched in the order they were registered when the task is scheduled to run.
* All of the "task restart callouts" so dispatched run to completion before the task regains
* control at its starting address.
* The t_restart() call accepts a new set of up to four arguments, which, among
* other things, can be used by the task to distinguish between the initial startup and
* subsequent restarts.
* The calling task does not have to be the creator (or parent) of the task it restarts.
* However, a task must be restarted from the node on which it was created.
*/
unsigned long t_restart (
unsigned long tid, /* task identifier */
unsigned long targs[4] /* startup arguments */
);
/*
* This system call removes the suspension of a task. If the task was suspended while
* in the ready state, t_resume() releases it to be scheduled for execution. If the task
* was both suspended and blocked (for example, waiting for a message), t_resume()
* removes only the suspension. This leaves the task in the blocked state.
*/
unsigned long t_resume (
unsigned long tid /* task identifier */
);
/*
* This system call enables the calling task to optionally obtain and modify either its
* own or another task's base scheduling (software) priority. If oldprio is a non-NULL
* address, the previous base scheduling priority is returned in the variable pointed to
* by oldprio, regardless of the task's current priority. If the calling task issues
* t_setpri() for a target task (self or another) with a valid non-0 value of newprio,
* then the target task (whether it is running or not running) shall resume execution
* after all other runnable tasks of equal or greater priority have been scheduled to
* run.
*/
unsigned long t_setpri (
unsigned long tid, /* task identifier */
unsigned long newprio, /* new priority */
unsigned long *oldprio /* previous priority */
);
/*
* This system call enables the caller to modify the contents of a task's notepad register.
* Each task has 16 such software registers, held in the task's TCB. The purpose
* of these registers is to furnish every task with a set of named, permanent variables.
* Eight of these registers are reserved for system use, and eight are free to be used for
* application-specific purposes.
*/
unsigned long t_setreg (
unsigned long tid, /* task identifier */
unsigned long regnum, /* register number */
unsigned long reg_value /* register value */
);
/*
* This system call places a newly created task into the ready state to await scheduling
* for execution. Thereafter, pSOS+ posts any "task startup callouts" that are dispatched
* in the order they were registered when the task is scheduled to run. All of
* the "task startup callouts" so dispatched run to completion before the task regains
* control at its starting address. The calling task does not have to be the creator (or
* parent) of the task to be started. However, a task must be started from the node on
* which it was created.
*/
unsigned long t_start (
unsigned long tid, /* task identifier */
unsigned long mode, /* initial task attributes */
void (*start_addr) (unsigned long), /* task address */
unsigned long targs[4] /* startup task arguments */
);
/*
* This system call suspends execution of a task until a t_resume() call is made for
* the suspended task. The calling task suspends either itself or another task. The
* t_suspend() call prevents the specified task from contending for CPU time but
* does not directly prevent contention for any other resource.
*/
unsigned long t_suspend (
unsigned long tid /* task identifier */
);
/*
* This system call enables the calling task to obtain and optionally modify its own or
* another task's timeslice quantum. It allows applications to control how much execution
* time is distributed among tasks with the same priority. It also returns the previous
* timeslice quantum.
*/
unsigned long t_tslice (
unsigned long tid, /* task identifier */
unsigned long new_tslice, /* new timeslice value*/
unsigned long *old_tslice /* old timeslice value */
);
/* system calls for mutext */
#define MU_GLOBAL 0x0001 /* Mutex is globally addressable by other nodes of a multiprocessor system. The single-processor version of the pSOS+ kernel ignores MU_GLOBAL. */
#define MU_LOCAL 0x0002 /* Mutex can be addressed only by the local node where it was created. */
#define MU_RECURSIVE 0x0004 /* Mutex can be acquired in a recursive fashion. */
#define MU_NORECURSIVE 0x0008 /* Mutex cannot be acquired in a recursive fashion. */
#define MU_FIFO 0x0010 /* The waiting tasks are queued in the FIFO order. This flag can be specified with MU_PRIO_NONE flag, but not with MU_PRIO_INHERIT or MU_PRIO_PROTECT. */
#define MU_PRIOR 0x0020 /* The waiting tasks are queued in decreasing order of their current priority. */
#define MU_PRIO_NONE 0x0100 /* Mutex does not protect against unbounded priority inversion. */
#define MU_PRIO_INHERIT 0x0200 /* Mutex uses the priority inheritance protocol to prevent unbounded priority inversion. */
#define MU_PRIO_PROTECT 0x0400 /* Mutex uses the priority protect protocol to prevent unbounded priority inversion. */
/*
* This system call creates a mutex and initializes it according to the specifications
* supplied with the call.
*/
unsigned long mu_create (
char name[4], /* user assigned name */
unsigned long flags, /* mutex attributes */
unsigned long ceiling, /* ceiling priority */
unsigned long *muid /* newly created mutex id */
);
/*
* This system call deletes a mutex with the specified mutex ID and frees the associated
* kernel resources. This call can be made only from the node where the specified
* mutex was created.
* The mu_delete() system call can be invoked by any task, and not necessarily the
* task that originally created the mutex. In the event that there are other tasks waiting
* to acquire that mutex, the tasks are unblocked and an error code is returned to
* them.
*/
unsigned long mu_delete (
unsigned long muid /* MUTEX identifier */
);
/*
* This system call enables the calling task to obtain the mutex ID of a mutex it only
* knows by name. This mutex ID can be used in all other operations relating to the
* mutex.
* The pSOS+ kernel does not check for duplicate names. If multiple mutexes with the
* same name exist, either on the local node, or on a remote note in a multi-processor
* system, a mu_ident() call may return the ID of any one mutex with the specified
* name. It can't be ascertained which ID is returned, though, to a certain extent it depends
* on the standard search order followed by pSOS+ kernel, as defined in the
* pSOSystem System Concepts manual.
*/
unsigned long mu_ident (
char name[4], /* mutex name */
unsigned long node, /* node number */
unsigned long *muid /* mutex identifier */
);
struct muinfo {
char name[4]; /* Name of the Mutex */
unsigned long flags; /* Mutex attributes */
unsigned long wqlen; /* No. of waiting tasks */
unsigned long wtid;/* ID of the first waiting task */
unsigned long count; /* Mutex reference count */
unsigned long ownid; /* ID of mutex owner */
unsigned long node; /* Owner task's node number */
unsigned long ceilprio; /* ceiling priority for MU_PROTECT mutexes */
unsigned long phpwt; /* Highest of all waiting task priorities */
};
/*
* This system call provides information of a specified Mutex object. The information
* includes the static information that was specified at object creation time and certain
* internal state information which is not static.
*/
unsigned long mu_info (
unsigned long muid, /* Mutex ID */
struct muinfo *buf /* Object Information buffer */
);
#define MU_WAIT 0x01 /* If the mutex is locked, block until it is available. */
#define MU_NOWAIT 0x02 /* Return with error if the mutex is locked. */
/*
* This system call allows a task to lock a mutex specified by the muid argument. If the
* mutex is not locked by another task, the mutex is put in the locked state, and the
* calling task becomes the owner of the mutex. If the mutex was created with the
* MU_RECURSIVE attribute set (see mu_create on page 2-87), a task can invoke
* mu_lock() multiple times to acquire the same mutex in a recursive fashion. The
* same number of mu_unlock() calls must then be made by the same task to release
* the mutex. A mutex created with the MU_NORECURSIVE flag can be locked only once
* by any task. If the task calls mu_lock again while it is holding the mutex, the call
* will return with an error.
* If the mutex is locked by another task then, depending on the flags argument, the
* calling task is either put in the blocked state and is queued in the wait queue associated
* with the mutex, or an error is returned.
*/
unsigned long mu_lock (
unsigned long muid, /* mutex identifier */
unsigned long flags, /* call attributes */
unsigned long timeout /* timeout interval */
);
/*
* This system call enables the calling task to optionally obtain and modify a mutex's
* ceiling priority. The call only operates on mutexes that have been created with the
* MU_PRIO_PROTECT flag. If oldprio is a non-NULL address, the previous ceiling priority
* is returned in the variable pointed to by oldprio.
* The mu_setceil() call either locks the mutex if it is unlocked, or blocks until it
* can successfully lock the mutex; then it changes the priority ceiling of the mutex
* and releases the mutex. If the calling task already owns the mutex when it invokes
* the mu_setceil() call with a valid non-0 value of newprio, then the task's current
* priority may change according to the priority protect protocol.
*/
unsigned long mu_setceil (
unsigned long muid, /* mutex identifier */
unsigned long newprio, /* new ceiling priority */
unsigned long *oldprio /* previous ceiling priority */
);
/*
* This system call allows a task to unlock a mutex specified by the muid argument. If
* the caller currently owns the mutex then mu_unlock() call decreases the recursive
* level associated with the mutex. If the recursive level reaches zero, the mutex is unlocked
* and the calling task loses ownership of the mutex. An error is returned if the
* calling task does not currently own the mutex.
* For mutexes which have not been created with the MU_PRIO_PROTECT flag, when
* the calling task loses the ownership of the mutex, and if any tasks are waiting to
* lock the mutex, the ownership of the mutex is transferred to the waiting task at the
* head of the mutex's wait queue. It is unblocked, and made ready-to-run.
* For mutexes which have been created with the MU_PRIO_PROTECT flag, when the
* calling task loses ownership of the mutex, there could be tasks waiting at the mutex's
* wait queue, on one of two action types. If the task at the head of the queue is
* waiting to lock the mutex, the ownership of the mutex is transferred to the waiting
* task, and its priority is raised if necessary. It is unblocked, and made ready-to-run.
* If the task at the head of the queue is waiting to change the ceiling priority of the
* mutex, the ceiling priority is modified, the task is unblocked and made ready-torun;
* and the next task in the waiting queue is checked. This process of determining
* the requested action type associated with a waiting task goes on till either the queue
* is empty, or a task which can successfully lock the mutex is found.
*/
unsigned long mu_unlock (
unsigned long muid /* mutex identifier */
);
/*
* This system call is used to asynchronously release a semaphore token. It is identical
* to sm_v() except the call is made asynchronously. Refer to the description of
* sm_v() for further information. This call is only supported by the pSOS+m kernel
* (the multiprocessor version).
*/
unsigned long sm_av (
unsigned long smid /* semaphore identifier */
);
#define SM_GLOBAL 0x0001 /* Semaphore can be addressed by other nodes. */
#define SM_LOCAL 0x0002 /* Semaphore can be addressed by local node only. */
#define SM_PRIOR 0x0004 /* Tasks are queued by priority. */
#define SM_FIFO 0x0008 /* Tasks are queued by FIFO. */
#define SM_UNBOUNDED 0x0010 /* Semaphore count is not bounded. */
#define SM_BOUNDED 0x0020 /* Semaphore count is bounded. When the SM_BOUNDED flag is specified the count parameter specifies the initial semaphore token count, as well as the upper bound of available tokens. */
/*
* This system call creates a semaphore by allocating and initializing a Semaphore
* Control Block (SMCB) according to the specifications supplied with the call.
* Like all objects, a semaphore has a user-assigned name, and a pSOS+-assigned
* semaphore ID returned by sm_create(). Several flag bits specify the characteristics
* of the semaphore, including whether tasks will wait for the semaphore by task
* priority or strictly FIFO.
*/
unsigned long sm_create (
char name[4], /* semaphore name */
unsigned long count, /* number of tokens */
unsigned long flags, /* semaphore attributes */
unsigned long *smid /* semaphore identifier */
);
/*
* This system call deletes the semaphore with the specified semaphore ID, and frees
* the SMCB to be reused. sm_delete() takes care of cleaning up the semaphore. If
* there are tasks waiting, they will be unblocked and given an error code.
* The calling task does not have to be the creator (parent) of the semaphore to be deleted.
* However, a semaphore must be deleted from the node on which it was created.
*/
unsigned long sm_delete (
unsigned long smid /* semaphore ID */
);
/*
* This system call enables the calling task to obtain the semaphore ID of a semaphore
* it only knows by name. The semaphore ID can then be used in all other operations
* relating to this semaphore.
* Most system calls, except sm_create() and sm_ident(), reference a semaphore
* by the semaphore ID. sm_create() returns the semaphore ID to the semaphore
* creator. For other tasks, one way to obtain the semaphore ID is to use sm_ident().
*/
unsigned long sm_ident (
char name[4], /* semaphore name */
unsigned long node, /* node selector */
unsigned long *smid /* semaphore ID */
);
struct sminfo {
char name[4]; /* Name of semaphore */
unsigned long flags; /* Semaphore attributes */
unsigned long wqlen; /* No. of waiting tasks */
unsigned long wtid; /* ID of the first waiting task */
unsigned long count; /* Semaphore count */
unsigned long maxcount; /* Limit for bounded semaphores */
unsigned long tid_ntfy; /* Task to notify of availability */
unsigned long ev_ntfy; /* Ev to post to notify availability */
};
/*
* This system call returns information of a specified Semaphore object. The information
* includes the static information that was specified at object creation time and
* certain internal state information which is not static.
*/
unsigned long sm_info (
unsigned long smid, /* Semaphore ID */
struct sminfo *buf /* Object Information buffer */
);
/*
* This system call registers a set of bit-encoded events and a task ID for the given
* semaphore. Once so registered, a notification is sent to the task whenever a semaphore
* token becomes available, via an implicit call of the form: ev_send(tid,
* events). The task can choose to receive the notification via ev_receive() call.
*/
unsigned long sm_notify (
unsigned long smid, /* ID of target semaphore */
unsigned long tid, /* ID of task to be notified */
unsigned long events /* bit-encoded events */
);
#define SM_WAIT 0x01 /* Block until semaphore is available. */
#define SM_NOWAIT 0x02 /* Return with error code if semaphore is unavailable. */
/*
* This system call enables a task or an ISR to acquire a semaphore token. A calling
* task can specify whether or not it wants to wait for the token. If the semaphore token
* count is positive, then this call returns the semaphore token immediately. If the
* semaphore token count is zero and the calling task specified SM_NOWAIT, then
* sm_p() returns with an error code. If SM_WAIT is elected, the task will be blocked
* until a semaphore token is released, or if the timeout argument is specified, until
* timeout occurs, whichever occurs first.
*/
unsigned long sm_p (
unsigned long smid, /* semaphore identifier */
unsigned long flags, /* attributes */
unsigned long timeout /* timeout */
);
/*
* This system call is used to release a semaphore token. If a task is already waiting at
* the semaphore, it is unblocked and made ready to run. If there is no task waiting,
* then the semaphore token count is simply incremented by 1.
* If, as a result of this call, a semaphore token becomes available, and a set of task
* and events had been registered via a prior call to sm_vnotify() to notify the availability
* of the semaphore token, pSOS+ also performs an ev_send() operation to
* send the registered events to the registered task.
*/
unsigned long sm_v (
unsigned long smid /* semaphore identifier */
);
/*
* This system call asynchronously removes all tasks from a condition-variable<6C><65>s wait
* queue. It is identical to cv_broadcast() except that the call is made asynchro-
* nously. Refer to the description of cv_broadcast() for further information.
*/
unsigned long cv_abroadcast (
unsigned long cvid /* condition variable identifier */
);
/*
* This system call asynchronously removes the task at the head of a condition-
* variable<6C><65>s queue. It is identical to cv_signal() except that the call is made asyn-
* chronously. Refer to the description of cv_signal() for further information.
*/
unsigned long cv_asignal (
unsigned long cvid /* condition variable ID */
);
/*
* This system call removes all the tasks from a condition variable<6C><65>s wait queue. If the
* mutex guarding the condition variable is unlocked, the task at the head of the wait
* queue is given ownership of the guarding mutex and unblocked. The remaining
* tasks, including the task at the head of the wait queue if the guarding mutex is
* locked, are placed in the guarding mutex<65><78>s wait queue.
* If there are no tasks waiting, then cv_broadcast() does not do anything.
*/
unsigned long cv_broadcast (
unsigned long cvid /* condition variable identifier */
);
/*
* This system call creates a condition variable and initializes it according to the
* specifications supplied with the call.
* Like all objects, a condition variable has a user-assigned name and a pSOS-
* assigned condition variable ID returned by cv_create(). Several flag bits specify
* the characteristics of the condition variable. Tasks can wait at the condition variable
* either by task priority or strictly FIFO.
*/
unsigned long cv_create (
char name[4],
unsigned long flags,
unsigned long *cvid
);
/*
* This system call deletes a condition variable specified by its ID (cvid) and frees the
* associated kernel resources. If there are tasks waiting at the condition variable, the
* tasks are unblocked and given an error code.
* The calling task does not have to be the creator of the condition variable to be de-
* leted. However, a condition variable must be deleted from the node on which it was
* created.
*/
unsigned long cv_delete (
unsigned long cvid /* condition variable identifier */
);
/*
* This system call enables the calling task to obtain the ID of a condition variable it
* only knows by name. This condition variable ID can be used in all other operations
* relating to the condition variable.
* The pSOS+ kernel does not check for duplicate names. If multiple condition vari-
* ables with the same name exist, either on the local node, or on a remote note in a
* multi-processor system, a cv_ident() call may return the ID of any one condition
* variable with the specified name. It can<61><6E>t be ascertained which ID is returned,
* though; to a certain extent it depends on the standard search order followed by
* pSOS+ kernel, as defined in the pSOSystem System Concepts manual.
*/
unsigned long cv_ident (
char name[4], /* condition variable name */
unsigned long node, /* node number */
unsigned long *cvid /* condition variable identifier */
);
#if 0
/*
* This system call returns object information for a given condition variable object. The
* information includes the static information that was specified at object creation
* time and certain internal state information which is not static.
*/
unsigned long cv_info (
unsigned long cvid,
struct cvinfo *buf
);
#endif
/*
* This system call removes the task at the head of a condition variable<6C><65>s wait queue
* from that queue. If the mutex guarding the condition variable is unlocked, the task
* is given ownership of the guarding mutex and unblocked. If the mutex is already
* locked, then the task is placed in the guarding mutex<65><78>s wait queue according to the
* queueing policy of the mutex.
* If there are no tasks waiting at the condition variable, this call does nothing.
*/
unsigned long cv_signal (
unsigned long cvid /* condition variable identifier */
);
/*
* This system call is used by a task to wait on a condition variable. The guarding mu-
* tex must be owned by the caller. If tasks are waiting at the condition variable, then
* muid must specify the mutex already guarding the condition variable. Otherwise,
* any mutex may be specified.
* cv_wait() unlocks the guarding mutex and blocks the calling task. Unless a time-
* out occurs, the calling task waits at the condition variable until removed from the
* wait queue by a cv_signal() or a cv_broadcast() call. When removed, owner-
* ship of the guarding mutex is given to the task if the guarding mutex is currently
* unlocked. Otherwise, the task waits for ownership of the guarding mutex according
* to the queueing policy of the mutex.
*/
unsigned long cv_wait (
unsigned long cvid, /* condition variable identifier */
unsigned long muid, /* mutex identifier */
unsigned long timeout /* timeout interval */
);
/*
* This system call returns the address of the calling task's internal errno variable.
* The pSOS+ kernel maintains an internal errno variable for every task. Whenever
* an error is detected by any pSOSystem component, the associated error code is
* stored into the running task's internal errno variable. The error code can then be
* retrieved by referencing the errno macro de????ed in the header ????e <psos.h> as
* follows:
* #define errno (*(errno_addr())
* For example, the following statement expands to include a call to errno_addr():
* if (errno == ERR_NOMGB)
*/
unsigned long *errno_addr (void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _PSOS_H */