FreeCalypso > hg > fc-selenite
changeset 7:0f80e1e4dce4
src/nucleus: library C code import from FreeNucleus package
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/cs_defs.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,89 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* cs_defs.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* CS - Common Services */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains data structure definitions used in the common */ +/* service linked list routines. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* CS_NODE Link node structure */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* nucleus.h Nucleus PLUS constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 06-01-1993 Added padding conditional into */ +/* CS_NODE structure, making */ +/* version 1.0a */ +/* 06-01-1993 Verified version 1.0a */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "nucleus.h" /* Include Nucleus constants */ + + +/* Check to see if the file has been included already. */ +#ifndef CS_DEFS +#define CS_DEFS + + +/* Define a common node data structure that can be included inside of + other system data structures. */ + +typedef struct CS_NODE_STRUCT +{ + struct CS_NODE_STRUCT *cs_previous; + struct CS_NODE_STRUCT *cs_next; + DATA_ELEMENT cs_priority; + +#if PAD_1 + DATA_ELEMENT cs_padding[PAD_1]; +#endif + +} CS_NODE; + +#endif /* CS_DEFS */ + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/cs_extr.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,125 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* cs_extr.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* CS - Common Services */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains function prototypes of all functions */ +/* accessible to other components. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_defs.h Common service definitions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* added inline capability for */ +/* linked-list functions, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 02-02-1998 Corrected SPR347 where NU_INLINE */ +/* created a linker error because */ +/* CSC_Priority_Place_On_List was */ +/* "extern"d instead of "VOID"d */ +/* resulting in version 1.2a */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "cs_defs.h" /* Include CS definitions */ + + +/* Check to see if the file has been included already. */ + +#ifndef CS_EXTR +#define CS_EXTR + +#ifndef NU_INLINE +VOID CSC_Place_On_List(CS_NODE **head, CS_NODE *new_node); +VOID CSC_Priority_Place_On_List(CS_NODE **head, CS_NODE *new_node); +VOID CSC_Remove_From_List(CS_NODE **head, CS_NODE *node); +#else +#define CSC_Place_On_List(head, new_node); \ + if (*((CS_NODE **) (head))) \ + { \ + ((CS_NODE *) (new_node)) -> cs_previous= \ + (*((CS_NODE **) (head))) -> cs_previous; \ + (((CS_NODE *) (new_node)) -> cs_previous) -> cs_next = \ + (CS_NODE *) (new_node); \ + ((CS_NODE *) (new_node)) -> cs_next = \ + (*((CS_NODE **) (head))); \ + (((CS_NODE *) (new_node)) -> cs_next) -> cs_previous = \ + ((CS_NODE *) (new_node)); \ + } \ + else \ + { \ + (*((CS_NODE **) (head))) = ((CS_NODE *) (new_node)); \ + ((CS_NODE *) (new_node)) -> cs_previous = \ + ((CS_NODE *) (new_node)); \ + ((CS_NODE *) (new_node)) -> cs_next = \ + ((CS_NODE *) (new_node)); \ + } + +VOID CSC_Priority_Place_On_List(CS_NODE **head, CS_NODE *new_node); + +#define CSC_Remove_From_List(head, node); \ + if (((CS_NODE *) (node)) -> cs_previous == \ + ((CS_NODE *) (node))) \ + { \ + (*((CS_NODE **) (head))) = NU_NULL; \ + } \ + else \ + { \ + (((CS_NODE *) (node)) -> cs_previous) -> cs_next = \ + ((CS_NODE *) (node)) -> cs_next; \ + (((CS_NODE *) (node)) -> cs_next) -> cs_previous = \ + ((CS_NODE *) (node)) -> cs_previous; \ + if (((CS_NODE *) (node)) == *((CS_NODE **) (head))) \ + *((CS_NODE **) (head)) = \ + ((CS_NODE *) (node)) -> cs_next; \ + } +#endif + +#endif + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/csc.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,324 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* csc.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* CS - Common Services */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains linked list manipulation facilities used */ +/* throughout the Nucleus PLUS system. These facilities operate */ +/* on doubly-linked circular lists. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* CSC_Place_On_List Place node at the end of a */ +/* list */ +/* CSC_Priority_Place_On_List Place node in priority order */ +/* on a list */ +/* CSC_Remove_From_List Remove a node from a list */ +/* */ +/* DEPENDENCIES */ +/* */ +/* nucleus.h Nucleus PLUS constants */ +/* cs_defs.h Common service definitions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed void to VOID, removed */ +/* clearing link pointers during */ +/* removal of a node from a list, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_defs.h" /* Include CS definitions */ +#include "cs_extr.h" /* Common service functions */ + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* CSC_Place_On_List */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function places the specified node at the end of specified */ +/* linked list. */ +/* */ +/* CALLED BY */ +/* */ +/* various components */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* head Pointer to head pointer */ +/* node Pointer to node to add */ +/* */ +/* OUTPUTS */ +/* */ +/* modified list */ +/* */ +/* HISTORY */ +/* */ +/* NAME DATE REMARKS */ +/* */ +/* W. Lamie 03-01-1993 Created initial version 1.0 */ +/* D. Lamie 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ + +#ifndef NU_INLINE + +VOID CSC_Place_On_List(CS_NODE **head, CS_NODE *new_node) +{ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Determine if the list in non-empty. */ + if (*head) + { + + /* The list is not empty. Add the new node to the end of + the list. */ + new_node -> cs_previous = (*head) -> cs_previous; + (new_node -> cs_previous) -> cs_next = new_node; + new_node -> cs_next = (*head); + (new_node -> cs_next) -> cs_previous = new_node; + } + else + { + + /* The list is empty, setup the head and the new node. */ + (*head) = new_node; + new_node -> cs_previous = new_node; + new_node -> cs_next = new_node; + } + + /* Return to user mode */ + NU_USER_MODE(); +} + +#endif + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* CSC_Priority_Place_On_List */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function places the specified node after all other nodes on */ +/* the list of equal or greater priority. Note that lower */ +/* numerical values indicate greater priority. */ +/* */ +/* CALLED BY */ +/* */ +/* various components */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* head Pointer to head pointer */ +/* node Pointer to node to add */ +/* */ +/* OUTPUTS */ +/* */ +/* modified list */ +/* */ +/* HISTORY */ +/* */ +/* NAME DATE REMARKS */ +/* */ +/* W. Lamie 03-01-1993 Created initial version 1.0 */ +/* D. Lamie 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ + +VOID CSC_Priority_Place_On_List(CS_NODE **head, CS_NODE *new_node) +{ + +CS_NODE *search_ptr; /* List search pointer */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Determine if the list in non-empty. */ + if (*head) + { + + /* Search the list to find the proper place for the new node. */ + search_ptr = (*head); + + /* Check for insertion before the first node on the list. */ + if (search_ptr -> cs_priority > new_node -> cs_priority) + { + + /* Update the head pointer to point at the new node. */ + (*head) = new_node; + } + else + { + + /* We know that the new node is not the highest priority and + must be placed somewhere after the head pointer. */ + + /* Move search pointer up to the next node since we are trying + to find the proper node to insert in front of. */ + search_ptr = search_ptr -> cs_next; + while ((search_ptr -> cs_priority <= new_node -> cs_priority) && + (search_ptr != (*head))) + { + + /* Move along to the next node. */ + search_ptr = search_ptr -> cs_next; + } + } + + /* Insert before search pointer. */ + new_node -> cs_previous = search_ptr -> cs_previous; + (new_node -> cs_previous) -> cs_next = new_node; + new_node -> cs_next = search_ptr; + (new_node -> cs_next) -> cs_previous = new_node; + } + else + { + + /* The list is empty, setup the head and the new node. */ + (*head) = new_node; + new_node -> cs_previous = new_node; + new_node -> cs_next = new_node; + } + + /* Return to user mode */ + NU_USER_MODE(); +} + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* CSC_Remove_From_List */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function removes the specified node from the specified */ +/* linked list. */ +/* */ +/* CALLED BY */ +/* */ +/* various components */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* head Pointer to head pointer */ +/* node Pointer to node to add */ +/* */ +/* OUTPUTS */ +/* */ +/* modified list */ +/* */ +/* HISTORY */ +/* */ +/* NAME DATE REMARKS */ +/* */ +/* W. Lamie 03-01-1993 Created initial version 1.0 */ +/* D. Lamie 04-19-1993 Verified version 1.0 */ +/* W. Lamie 03-01-1994 Removed clearing link pointers */ +/* during removal of a node from */ +/* list, resulting in version 1.1 */ +/* R. Pfaff - */ +/* D. Lamie 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ + +#ifndef NU_INLINE + +VOID CSC_Remove_From_List(CS_NODE **head, CS_NODE *node) +{ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Determine if this is the only node in the system. */ + if (node -> cs_previous == node) + { + + /* Yes, this is the only node in the system. Clear the node's + pointers and the head pointer. */ + (*head) = NU_NULL; + } + else + { + + /* Unlink the node from a multiple node list. */ + (node -> cs_previous) -> cs_next = node -> cs_next; + (node -> cs_next) -> cs_previous = node -> cs_previous; + + /* Check to see if the node to delete is at the head of the + list. */ + if (node == *head) + + /* Move the head pointer to the node after. */ + *head = node -> cs_next; + } + + /* Return to user mode */ + NU_USER_MODE(); +} + +#endif + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/dm_defs.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,153 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* dm_defs.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* DM - Dynamic Memory Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains data structure definitions and constants for */ +/* the Dynamic Memory component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* DM_PCB Dynamic Pool control block */ +/* DM_HEADER Header of each memory block */ +/* DM_SUSPEND Memory suspension block */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_defs.h Common service definitions */ +/* tc_defs.h Thread Control definitions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* added padding logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 01-07-1997 Added missing PAD_1 field to */ +/* DM_HEADER_STRUCT to be */ +/* consistent with other PLUS */ +/* structures creating 1.2a. */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "cs_defs.h" /* Common service constants */ +#include "tc_defs.h" /* Thread control constants */ + + +/* Check to see if the file has been included already. */ + +#ifndef DM_DEFS +#define DM_DEFS + + +/* Adjust a size to something that is evenly divisible by the number of bytes + in an UNSIGNED data type. */ + +#define DM_ADJUSTED_SIZE(size) \ + ((((size) + sizeof(UNSIGNED) - 1)/sizeof(UNSIGNED)) * sizeof(UNSIGNED)) + +#define DM_ADJUSTED_ALIGNMENT(alignment) DM_ADJUSTED_SIZE(alignment) + +/* Define constants local to this component. */ + +#define DM_DYNAMIC_ID 0x44594e41UL +#define DM_OVERHEAD ((sizeof(DM_HEADER) + sizeof(UNSIGNED) \ + - 1)/sizeof(UNSIGNED)) * \ + sizeof(UNSIGNED) + + +/* Define the Dynamic Pool Control Block data type. */ + +typedef struct DM_PCB_STRUCT +{ + CS_NODE dm_created; /* Node for linking to */ + /* created dynamic pools */ + TC_PROTECT dm_protect; /* Protection structure */ + UNSIGNED dm_id; /* Internal PCB ID */ + CHAR dm_name[NU_MAX_NAME]; /* Dynamic Pool name */ + VOID *dm_start_address; /* Starting pool address */ + UNSIGNED dm_pool_size; /* Size of pool */ + UNSIGNED dm_min_allocation; /* Minimum allocate size */ + UNSIGNED dm_available; /* Total available bytes */ + struct DM_HEADER_STRUCT + *dm_memory_list; /* Memory list */ + struct DM_HEADER_STRUCT + *dm_search_ptr; /* Search pointer */ + BOOLEAN dm_fifo_suspend; /* Suspension type flag */ +#if PAD_1 + DATA_ELEMENT dm_padding[PAD_1]; +#endif + UNSIGNED dm_tasks_waiting; /* Number of waiting tasks*/ + struct DM_SUSPEND_STRUCT + *dm_suspension_list; /* Suspension list */ +} DM_PCB; + + +/* Define the header structure that is in front of each memory block. */ + +typedef struct DM_HEADER_STRUCT +{ + struct DM_HEADER_STRUCT + *dm_next_memory, /* Next memory block */ + *dm_previous_memory; /* Previous memory block */ + BOOLEAN dm_memory_free; /* Memory block free flag */ +#if PAD_1 + DATA_ELEMENT dm_padding[PAD_1]; +#endif + DM_PCB *dm_memory_pool; /* Dynamic pool pointer */ +} DM_HEADER; + + +/* Define the dynamic memory suspension structure. This structure is + allocated off of the caller's stack. */ + +typedef struct DM_SUSPEND_STRUCT +{ + CS_NODE dm_suspend_link; /* Link to suspend blocks */ + DM_PCB *dm_memory_pool; /* Pointer to pool */ + UNSIGNED dm_request_size; /* Size of memory request */ + TC_TCB *dm_suspended_task; /* Task suspended */ + VOID *dm_return_pointer; /* Return memory address */ + STATUS dm_return_status; /* Return status */ +} DM_SUSPEND; + +#endif + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/dm_extr.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,122 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* dm_extr.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* DM - Dynamic Memory Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains function prototypes of all functions */ +/* accessible to other components. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* dm_defs.h Dynamic Management constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* modified function prototypes, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 05-01-2000 Corrected a prefix problem for */ +/* DMC_Established_Memory_Pools, */ +/* DMC_Memory_Pool_Information, */ +/* DMC_Memory_Pool_Pointers by */ +/* changing them to DMF_ */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "dm_defs.h" /* Include DM constants */ + + +/* Check to see if the file has been included already. */ + +#ifndef DM_EXTR +#define DM_EXTR + + +/* Initialization functions. */ + +VOID DMI_Initialize(VOID); + + +/* Error checking functions. */ + +STATUS DMCE_Create_Memory_Pool(NU_MEMORY_POOL *pool_ptr, CHAR *name, + VOID *start_address, UNSIGNED pool_size, + UNSIGNED min_allocation, OPTION suspend_type); +STATUS DMCE_Delete_Memory_Pool(NU_MEMORY_POOL *pool_ptr); +STATUS DMCE_Allocate_Memory(NU_MEMORY_POOL *pool_ptr, VOID **return_pointer, + UNSIGNED size, UNSIGNED suspend); +STATUS DMCE_Deallocate_Memory(VOID *memory); + + +/* Core processing functions. */ + +STATUS DMC_Create_Memory_Pool(NU_MEMORY_POOL *pool_ptr, CHAR *name, + VOID *start_address, UNSIGNED pool_size, + UNSIGNED min_allocation, OPTION suspend_type); +STATUS DMC_Delete_Memory_Pool(NU_MEMORY_POOL *pool_ptr); +STATUS DMC_Allocate_Memory(NU_MEMORY_POOL *pool_ptr, + VOID **return_pointer, UNSIGNED size, UNSIGNED suspend); +STATUS DMC_Deallocate_Memory(VOID *memory); + + +/* Supplemental service routines */ +STATUS DMS_Allocate_Aligned_Memory(NU_MEMORY_POOL *pool_ptr, + VOID **return_pointer, UNSIGNED size, + UNSIGNED alignment, UNSIGNED suspend); + + +/* Information retrieval functions. */ + +UNSIGNED DMF_Established_Memory_Pools(VOID); +STATUS DMF_Memory_Pool_Information(NU_MEMORY_POOL *pool_ptr, + CHAR *name, VOID **start_address, UNSIGNED *pool_size, + UNSIGNED *min_allocation, UNSIGNED *available, + OPTION *suspend_type, UNSIGNED *tasks_waiting, + NU_TASK **first_task); +UNSIGNED DMF_Memory_Pool_Pointers(NU_MEMORY_POOL **pointer_list, + UNSIGNED maximum_pointers); +#endif + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/dmc.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,1084 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* dmc.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* DM - Dynamic Memory Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the core routines for the Dynamic Memory */ +/* Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* DMC_Create_Memory_Pool Create a dynamic memory pool */ +/* DMC_Delete_Memory_Pool Delete a dynamic memory pool */ +/* DMC_Allocate_Memory Allocate a memory block from */ +/* a dynamic memory pool */ +/* DMC_Deallocate_Memory Deallocate a memory block */ +/* from a dynamic memory pool */ +/* DMC_Cleanup Cleanup on timeout or a */ +/* terminate condition */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* dm_extr.h Partition functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected pointer retrieval */ +/* loop, resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Moved non-core functions into */ +/* supplemental files, changed */ +/* function interfaces to match */ +/* those in prototype, added */ +/* register options, changed */ +/* protection logic to reduce */ +/* overhead, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "dm_extr.h" /* Dynamic memory functions */ +#include "hi_extr.h" /* History functions */ +#include "profiler.h" /* ProView interface */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *DMD_Created_Pools_List; +extern UNSIGNED DMD_Total_Pools; +extern TC_PROTECT DMD_List_Protect; + + +/* Define internal component function prototypes. */ + +VOID DMC_Cleanup(VOID *information); + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* DMC_Create_Memory_Pool */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function creates a dynamic memory pool and then places it */ +/* on the list of created dynamic memory pools. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* DMCE_Create_Memory_Pool Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Add node to linked-list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Data structure protect */ +/* TCT_Unprotect Un-protect data structure */ +/* */ +/* INPUTS */ +/* */ +/* pool_ptr Memory pool control block */ +/* pointer */ +/* name Memory pool name */ +/* start_address Starting address of the pool */ +/* pool_size Number of bytes in the pool */ +/* min_allocation Minimum allocation size */ +/* suspend_type Suspension type */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS DMC_Create_Memory_Pool(NU_MEMORY_POOL *pool_ptr, CHAR *name, + VOID *start_address, UNSIGNED pool_size, + UNSIGNED min_allocation, OPTION suspend_type) +{ + +R1 DM_PCB *pool; /* Pool control block ptr */ +INT i; /* Working index variable */ +DM_HEADER *header_ptr; /* Partition block header ptr*/ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input pool pointer into internal pointer. */ + pool = (DM_PCB *) pool_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_CREATE_MEMORY_POOL_ID, (UNSIGNED) pool, + (UNSIGNED) start_address, (UNSIGNED) pool_size); + +#endif + + /* First, clear the partition pool ID just in case it is an old + pool control block. */ + pool -> dm_id = 0; + + /* Fill in the partition pool name. */ + for (i = 0; i < NU_MAX_NAME; i++) + pool -> dm_name[i] = name[i]; + + /* Convert the pool's size into something that is evenly divisible by + the sizeof an UNSIGNED data element. */ + pool_size = (pool_size/sizeof(UNSIGNED)) * sizeof(UNSIGNED); + + /* Save the starting address and size parameters in the dynamic memory + control block. */ + pool -> dm_start_address = start_address; + pool -> dm_pool_size = pool_size; + pool -> dm_min_allocation = + ((min_allocation + sizeof(UNSIGNED) - 1)/sizeof(UNSIGNED)) * + sizeof(UNSIGNED); + + /* Setup the dynamic memory pool suspension type. */ + if (suspend_type == NU_FIFO) + + /* FIFO suspension is selected, setup the flag accordingly. */ + pool -> dm_fifo_suspend = NU_TRUE; + else + + /* Priority suspension is selected. */ + pool -> dm_fifo_suspend = NU_FALSE; + + /* Clear the suspension list pointer. */ + pool -> dm_suspension_list = NU_NULL; + + /* Clear the number of tasks waiting on the dynamic memory pool. */ + pool -> dm_tasks_waiting = 0; + + /* Initialize link pointers. */ + pool -> dm_created.cs_previous = NU_NULL; + pool -> dm_created.cs_next = NU_NULL; + + /* Build a single block that has all of the memory. */ + header_ptr = (DM_HEADER *) start_address; + + /* Initialize the memory parameters. */ + pool -> dm_available = pool_size - (2 * DM_OVERHEAD); + pool -> dm_memory_list = header_ptr; + pool -> dm_search_ptr = header_ptr; + + /* Build the block header. */ + header_ptr -> dm_memory_pool = pool; + header_ptr -> dm_memory_free = NU_TRUE; + header_ptr -> dm_next_memory = (DM_HEADER *) + (((BYTE_PTR) header_ptr) + pool -> dm_available + DM_OVERHEAD); + header_ptr -> dm_previous_memory = header_ptr -> dm_next_memory; + + /* Build the small trailer block that prevents block merging when the + pool wraps around. Note that the list is circular so searching can + wrap across the physical end of the memory pool. */ + header_ptr = header_ptr -> dm_next_memory; + header_ptr -> dm_next_memory = (DM_HEADER *) start_address; + header_ptr -> dm_previous_memory = (DM_HEADER *) start_address; + header_ptr -> dm_memory_pool = pool; + header_ptr -> dm_memory_free = NU_FALSE; + + /* Initialize the protection structure. */ + pool -> dm_protect.tc_tcb_pointer = NU_NULL; + + /* Protect against access to the list of created memory pools. */ + TCT_Protect(&DMD_List_Protect); + + /* At this point the dynamic memory pool is completely built. The ID can + now be set and it can be linked into the created dynamic memory + pool list. */ + pool -> dm_id = DM_DYNAMIC_ID; + + /* Link the memory pool into the list of created memory pools and + increment the total number of pools in the system. */ + CSC_Place_On_List(&DMD_Created_Pools_List, &(pool -> dm_created)); + DMD_Total_Pools++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMemoryPool(RT_PROF_CREATE_MEMORY_POOL,pool,RT_PROF_OK); +#endif /*INCLUDE_PROVIEW*/ + /* Release protection against access to the list of created memory + pools. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* DMC_Delete_Memory_Pool */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function deletes a dynamic memory pool and removes it from */ +/* the list of created memory pools. All tasks suspended on the */ +/* memory pool are resumed with the appropriate error status. */ +/* Note that this function does not free any memory associated with */ +/* either the pool area or the pool control block. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* DMCE_Delete_Memory_Pool Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove node from list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Protect Protect created list */ +/* TCT_Set_Current_Protect Modify current protection */ +/* TCT_System_Protect Setup system protection */ +/* TCT_System_Unprotect Release system protection */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* pool_ptr Memory pool control block */ +/* pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS DMC_Delete_Memory_Pool(NU_MEMORY_POOL *pool_ptr) +{ + +R1 DM_PCB *pool; /* Pool control block ptr */ +DM_SUSPEND *suspend_ptr; /* Suspend block pointer */ +DM_SUSPEND *next_ptr; /* Next suspend block */ +STATUS preempt; /* Status for resume call */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input pool pointer into internal pointer. */ + pool = (DM_PCB *) pool_ptr; + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_DELETE_MEMORY_POOL_ID, (UNSIGNED) pool, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Protect against simultaneous access to the memory pool. */ + TCT_Protect(&(pool -> dm_protect)); + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMemoryPool(RT_PROF_DELETE_MEMORY_POOL,pool,RT_PROF_OK); +#endif /*INCLUDE_PROVIEW*/ + /* Clear the memory pool ID. */ + pool -> dm_id = 0; + + /* Release protection. */ + TCT_Unprotect(); + + /* Protect against access to the list of created memory pools. */ + TCT_Protect(&DMD_List_Protect); + + /* Remove the memory pool from the list of created memory pools. */ + CSC_Remove_From_List(&DMD_Created_Pools_List, &(pool -> dm_created)); + + /* Decrement the total number of created memory pools. */ + DMD_Total_Pools--; + + /* Pickup the suspended task pointer list. */ + suspend_ptr = pool -> dm_suspension_list; + + /* Walk the chain task(s) currently suspended on the memory pool. */ + preempt = 0; + while (suspend_ptr) + { + + /* Protect against system access. */ + TCT_System_Protect(); + + /* Resume the suspended task. Insure that the status returned is + NU_POOL_DELETED. */ + suspend_ptr -> dm_return_pointer = NU_NULL; + suspend_ptr -> dm_return_status = NU_POOL_DELETED; + + /* Point to the next suspend structure in the link. */ + next_ptr = (DM_SUSPEND *) (suspend_ptr -> dm_suspend_link.cs_next); + + /* Resume the specified task. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> dm_suspended_task, + NU_MEMORY_SUSPEND); + + /* Determine if the next is the same as the current pointer. */ + if (next_ptr == pool -> dm_suspension_list) + + /* Clear the suspension pointer to signal the end of the list + traversal. */ + suspend_ptr = NU_NULL; + else + + /* Move the next pointer into the suspend block pointer. */ + suspend_ptr = next_ptr; + + /* Modify current protection. */ + TCT_Set_Current_Protect(&DMD_List_Protect); + + /* Clear the system protection. */ + TCT_System_Unprotect(); + } + + /* Determine if preemption needs to occur. */ + if (preempt) + + /* Transfer control to system to facilitate preemption. */ + TCT_Control_To_System(); + + /* Release protection against access to the list of created memory + pools. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return a successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* DMC_Allocate_Memory */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function allocates memory from the specified dynamic memory */ +/* pool. If dynamic memory is currently available, this function */ +/* is completed immediately. Otherwise, if there is not enough */ +/* memory currently available, task suspension is possible. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* DMCE_Allocate_Memory Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Place on suspend list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Suspend_Task Suspend calling task */ +/* TCC_Task_Priority Pickup task priority */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Current_Thread Pickup current thread pointer*/ +/* TCT_Protect Protect memory pool */ +/* TCT_Set_Suspend_Protect Save suspend protection */ +/* TCT_System_Protect Protect system structures */ +/* TCT_Unprotect Release protection */ +/* TCT_Unprotect_Specific Release specific protection */ +/* */ +/* INPUTS */ +/* */ +/* pool_ptr Memory pool pointer */ +/* return_pointer Pointer to the destination */ +/* memory pointer */ +/* size Number of bytes requested */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If service is successful */ +/* NU_NO_MEMORY Memory not available */ +/* NU_TIMEOUT If timeout on service */ +/* NU_POOL_DELETED If memory pool deleted */ +/* during suspension */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS DMC_Allocate_Memory(NU_MEMORY_POOL *pool_ptr, VOID **return_pointer, + UNSIGNED size, UNSIGNED suspend) +{ + +R1 DM_PCB *pool; /* Pool control block ptr */ +R2 DM_SUSPEND *suspend_ptr; /* Pointer to suspend block */ +DM_SUSPEND suspend_block; /* Allocate suspension block */ +R4 DM_HEADER *memory_ptr; /* Pointer to memory */ +R3 DM_HEADER *new_ptr; /* New split block pointer */ +UNSIGNED free_size; /* Size of block found */ +TC_TCB *task; /* Task pointer */ +STATUS status; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input pool pointer into internal pointer. */ + pool = (DM_PCB *) pool_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_ALLOCATE_MEMORY_ID, (UNSIGNED) pool, + (UNSIGNED) return_pointer, (UNSIGNED) size); + +#endif + + /* Initialize the status as successful. */ + status = NU_SUCCESS; + + /* Adjust the request to a size evenly divisible by the number of bytes + in an UNSIGNED data element. Also, check to make sure it is of the + minimum size. */ + if (size < pool -> dm_min_allocation) + + /* Change size to the minimum allocation. */ + size = pool -> dm_min_allocation; + else + + /* Insure that size is a multiple of the UNSIGNED size. */ + size = + ((size + sizeof(UNSIGNED) - 1)/sizeof(UNSIGNED)) * sizeof(UNSIGNED); + + /* Protect against simultaneous access to the memory pool. */ + TCT_Protect(&(pool -> dm_protect)); + + /* Search the memory list for the first available block of memory that + satisfies the request. Note that blocks are merged during the + deallocation function. */ + memory_ptr = pool -> dm_search_ptr; + do + { + + /* Determine if the block is free and if it can satisfy the request. */ + if (memory_ptr -> dm_memory_free) + + /* Calculate the free block size. */ + free_size = (((BYTE_PTR) (memory_ptr -> dm_next_memory)) - + ((BYTE_PTR) memory_ptr)) - DM_OVERHEAD; + else + + /* There are no free bytes available. */ + free_size = 0; + + /* Determine if the search should continue. */ + if (free_size < size) + + /* Large enough block has not been found. Move the search + pointer to the next block. */ + memory_ptr = memory_ptr -> dm_next_memory; + } while((free_size < size) && (memory_ptr != pool -> dm_search_ptr)); + + /* Determine if the memory is available. */ + if (free_size >= size) + { + + /* A block that satisfies the request has been found. */ + + /* Determine if the block needs to be split. */ + if (free_size >= (size + DM_OVERHEAD + pool -> dm_min_allocation)) + { + + /* Yes, split the block. */ + new_ptr = (DM_HEADER *) (((BYTE_PTR) memory_ptr) + size + + DM_OVERHEAD); + + /* Mark the new block as free. */ + new_ptr -> dm_memory_free = NU_TRUE; + + /* Put the pool pointer into the new block. */ + new_ptr -> dm_memory_pool = pool; + + /* Build the necessary pointers. */ + new_ptr -> dm_previous_memory = memory_ptr; + new_ptr -> dm_next_memory = memory_ptr -> dm_next_memory; + (new_ptr -> dm_next_memory) -> dm_previous_memory = new_ptr; + memory_ptr -> dm_next_memory = new_ptr; + + /* Decrement the available byte count. */ + pool -> dm_available = pool -> dm_available - size - DM_OVERHEAD; + } + else + + /* Decrement the entire free size from the available bytes + count. */ + pool -> dm_available = pool -> dm_available - free_size; + + /* Mark the allocated block as not available. */ + memory_ptr -> dm_memory_free = NU_FALSE; + + /* Should the search pointer be moved? */ + if (pool -> dm_search_ptr == memory_ptr) + + /* Move the search pointer to the next free memory slot. */ + pool -> dm_search_ptr = memory_ptr -> dm_next_memory; + + /* Return a memory address to the caller. */ + *return_pointer = (VOID *) (((BYTE_PTR) memory_ptr) + DM_OVERHEAD); +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMemoryPool(RT_PROF_ALLOCATE_MEMORY,pool,RT_PROF_OK); +#endif /*INCLUDE_PROVIEW*/ + } + else + { + + /* Enough dynamic memory is not available. Determine if suspension is + required. */ + if (suspend) + { + + /* Suspension is selected. */ + + /* Increment the number of tasks waiting. */ + pool -> dm_tasks_waiting++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMemoryPool(RT_PROF_ALLOCATE_MEMORY,pool,RT_PROF_WAIT); +#endif /*INCLUDE_PROVIEW*/ + /* Setup the suspend block and suspend the calling task. */ + suspend_ptr = &suspend_block; + suspend_ptr -> dm_memory_pool = pool; + suspend_ptr -> dm_request_size = size; + suspend_ptr -> dm_suspend_link.cs_next = NU_NULL; + suspend_ptr -> dm_suspend_link.cs_previous = NU_NULL; + task = (TC_TCB *) TCT_Current_Thread(); + suspend_ptr -> dm_suspended_task = task; + + /* Determine if priority or FIFO suspension is associated with the + memory pool. */ + if (pool -> dm_fifo_suspend) + { + + /* FIFO suspension is required. Link the suspend block into + the list of suspended tasks on this memory pool. */ + CSC_Place_On_List((CS_NODE **) + &(pool -> dm_suspension_list), + &(suspend_ptr -> dm_suspend_link)); + } + else + { + + /* Get the priority of the current thread so the suspend block + can be placed in the appropriate place. */ + suspend_ptr -> dm_suspend_link.cs_priority = + TCC_Task_Priority(task); + + CSC_Priority_Place_On_List((CS_NODE **) + &(pool -> dm_suspension_list), + &(suspend_ptr -> dm_suspend_link)); + } + + /* Protect against system access. */ + TCT_System_Protect(); + + /* Save the list protection in preparation for suspension. */ + TCT_Set_Suspend_Protect(&(pool -> dm_protect)); + + /* Release protection of dynamic memory pool. */ + TCT_Unprotect_Specific(&(pool -> dm_protect)); + + /* Finally, suspend the calling task. Note that the suspension call + automatically clears the system protection. */ + TCC_Suspend_Task((NU_TASK *) task, NU_MEMORY_SUSPEND, + DMC_Cleanup, suspend_ptr, suspend); + + /* Pickup the return status. */ + status = suspend_ptr -> dm_return_status; + *return_pointer = suspend_ptr -> dm_return_pointer; + } + else + { + + /* No suspension requested. Simply return an error status. */ + status = NU_NO_MEMORY; + *return_pointer = NU_NULL; +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMemoryPool(RT_PROF_ALLOCATE_MEMORY,pool,RT_PROF_FAIL); +#endif /*INCLUDE_PROVIEW*/ + } + } + + /* Release protection of the memory pool. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* DMC_Deallocate_Memory */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function deallocates a previously allocated dynamic memory */ +/* block. The deallocated dynamic memory block is merged with any */ +/* adjacent neighbors. This insures that there are no consecutive */ +/* blocks of free memory in the pool (makes the search easier!). */ +/* If there is a task waiting for dynamic memory, a determination */ +/* of whether or not the request can now be satisfied is made after */ +/* the deallocation is complete. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* DMCE_Deallocate_Memory Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove from suspend list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Set_Current_Protect Set current protection */ +/* TCT_System_Protect Protect system structures */ +/* TCT_System_Unprotect Release system protection */ +/* TCT_Protect Protect dynamic memory pool */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* memory Pointer to dynamic memory */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Added register options, changed */ +/* protection logic to reduce */ +/* overhead, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS DMC_Deallocate_Memory(VOID *memory) +{ + +R1 DM_PCB *pool; /* Pool pointer */ +R3 DM_SUSPEND *suspend_ptr; /* Pointer to suspend block */ +R2 DM_HEADER *header_ptr; /* Pointer to memory hdr */ +R4 DM_HEADER *new_ptr; /* New memory block pointer */ +UNSIGNED size; /* Suspended task request */ +UNSIGNED free_size; /* Amount of free bytes */ +STATUS preempt; /* Preemption flag */ +STATUS status; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_DEALLOCATE_MEMORY_ID, (UNSIGNED) memory, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Initialize the status as successful. */ + status = NU_SUCCESS; + + /* Pickup the associated pool's pointer. It is inside the header of + each memory. */ + header_ptr = (DM_HEADER *) (((BYTE_PTR) memory) - DM_OVERHEAD); + pool = header_ptr -> dm_memory_pool; + + /* Protect against simultaneous access to the memory pool. */ + TCT_Protect(&(pool -> dm_protect)); + + /* Mark the memory as available. */ + header_ptr -> dm_memory_free = NU_TRUE; + + /* Adjust the available number of bytes. */ + pool -> dm_available = pool -> dm_available + + (((BYTE_PTR) (header_ptr -> dm_next_memory)) - + ((BYTE_PTR) header_ptr)) - DM_OVERHEAD; + + /* Determine if the block can be merged with the previous neighbor. */ + if ((header_ptr -> dm_previous_memory) -> dm_memory_free) + { + + /* Adjust the available number of bytes. */ + pool -> dm_available = pool -> dm_available + DM_OVERHEAD; + + /* Yes, merge block with previous neighbor. */ + (header_ptr -> dm_previous_memory) -> dm_next_memory = + header_ptr -> dm_next_memory; + (header_ptr -> dm_next_memory) -> dm_previous_memory = + header_ptr -> dm_previous_memory; + + /* Move header pointer to previous. */ + header_ptr = header_ptr -> dm_previous_memory; + + /* Adjust the search pointer to the new merged block. */ + pool -> dm_search_ptr = header_ptr; + } + + /* Determine if the block can be merged with the next neighbor. */ + if ((header_ptr -> dm_next_memory) -> dm_memory_free) + { + + /* Adjust the available number of bytes. */ + pool -> dm_available = pool -> dm_available + DM_OVERHEAD; + + /* Yes, merge block with next neighbor. */ + new_ptr = header_ptr -> dm_next_memory; + (new_ptr -> dm_next_memory) -> dm_previous_memory = + header_ptr; + header_ptr -> dm_next_memory = new_ptr -> dm_next_memory; + + /* Adjust the search pointer to the new merged block. */ + pool -> dm_search_ptr = header_ptr; + } + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMemoryPool(RT_PROF_DEALLOCATE_MEMORY,pool,RT_PROF_OK); +#endif /*INCLUDE_PROVIEW*/ + /* Determine if another task is waiting for memory from the pool. */ + suspend_ptr = pool -> dm_suspension_list; + preempt = 0; + while (suspend_ptr) + { + + /* Yes, another task is waiting for memory from the pool. Search + the pool in the same manner as the memory allocation function. */ + size = suspend_ptr -> dm_request_size; + header_ptr = pool -> dm_search_ptr; + do + { + + /* Determine if the block is free and if it can satisfy the request + of the first task waiting. */ + if (header_ptr -> dm_memory_free) + + /* Calculate the free block size. */ + free_size = (((BYTE_PTR) (header_ptr -> dm_next_memory)) - + ((BYTE_PTR) header_ptr)) - DM_OVERHEAD; + else + + /* There are no free bytes available. */ + free_size = 0; + + /* Determine if the search should continue. */ + if (free_size < size) + + /* Large enough block has not been found. Move the search + pointer to the next block. */ + header_ptr = header_ptr -> dm_next_memory; + } while((free_size < size) && (header_ptr != pool -> dm_search_ptr)); + + /* Determine if the memory is available. */ + if (free_size >= size) + { + + /* A block that satisfies the request has been found. */ + + /* Determine if the block needs to be split. */ + if (free_size >= (size + DM_OVERHEAD + pool -> dm_min_allocation)) + { + + /* Yes, split the block. */ + new_ptr = (DM_HEADER *) (((BYTE_PTR) header_ptr) + size + + DM_OVERHEAD); + + /* Mark the new block as free. */ + new_ptr -> dm_memory_free = NU_TRUE; + + /* Put the pool pointer into the new block. */ + new_ptr -> dm_memory_pool = pool; + + /* Build the necessary pointers. */ + new_ptr -> dm_previous_memory = header_ptr; + new_ptr -> dm_next_memory = header_ptr -> dm_next_memory; + (new_ptr -> dm_next_memory) -> dm_previous_memory = new_ptr; + header_ptr -> dm_next_memory = new_ptr; + + /* Decrement the available byte count. */ + pool -> dm_available = pool -> dm_available - + size - DM_OVERHEAD; + } + else + + /* Decrement the entire free size from the available bytes + count. */ + pool -> dm_available = pool -> dm_available - free_size; + + /* Mark the allocated block as not available. */ + header_ptr -> dm_memory_free = NU_FALSE; + + /* Should the search pointer be moved? */ + if (pool -> dm_search_ptr == header_ptr) + + /* Move the search pointer to the next free memory slot. */ + pool -> dm_search_ptr = header_ptr -> dm_next_memory; + + /* Decrement the number of tasks waiting counter. */ + pool -> dm_tasks_waiting--; + + /* Remove the first suspended block from the list. */ + CSC_Remove_From_List((CS_NODE **) &(pool -> dm_suspension_list), + &(suspend_ptr -> dm_suspend_link)); + + /* Setup the appropriate return value. */ + suspend_ptr -> dm_return_status = NU_SUCCESS; + suspend_ptr -> dm_return_pointer = (VOID *) + (((BYTE_PTR) header_ptr) + DM_OVERHEAD); + + /* Setup system protect while task is being resumed. */ + TCT_System_Protect(); + + /* Resume the suspended task. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> dm_suspended_task, + NU_MEMORY_SUSPEND); + + /* Switch back to the pool protection. */ + TCT_Set_Current_Protect(&(pool -> dm_protect)); + + /* Release system protection. */ + TCT_System_Unprotect(); + + /* Pickup the next suspension pointer. */ + suspend_ptr = pool -> dm_suspension_list; + } + else + + /* Not enough memory for suspended task. */ + suspend_ptr = NU_NULL; + } + + /* Determine if a preempt condition is present. */ + if (preempt) + + /* Transfer control to the system if the resumed task function + detects a preemption condition. */ + TCT_Control_To_System(); + + /* Release protection of the memory pool. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* DMC_Cleanup */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for removing a suspension block */ +/* from a memory pool. It is not called unless a timeout or */ +/* a task terminate is in progress. Note that protection is */ +/* already in effect - the same protection at suspension time. */ +/* */ +/* CALLED BY */ +/* */ +/* TCC_Timeout Task timeout */ +/* TCC_Terminate Task terminate */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove suspend block from */ +/* the suspension list */ +/* */ +/* INPUTS */ +/* */ +/* information Pointer to suspend block */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +VOID DMC_Cleanup(VOID *information) +{ + +DM_SUSPEND *suspend_ptr; /* Suspension block pointer */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Use the information pointer as a suspend pointer. */ + suspend_ptr = (DM_SUSPEND *) information; + + /* By default, indicate that the service timed-out. It really does not + matter if this function is called from a terminate request since + the task does not resume. */ + suspend_ptr -> dm_return_status = NU_TIMEOUT; + suspend_ptr -> dm_return_pointer = NU_NULL; + + /* Decrement the number of tasks waiting counter. */ + (suspend_ptr -> dm_memory_pool) -> dm_tasks_waiting--; + + /* Unlink the suspend block from the suspension list. */ + CSC_Remove_From_List((CS_NODE **) + &((suspend_ptr -> dm_memory_pool) -> dm_suspension_list), + &(suspend_ptr -> dm_suspend_link)); + + /* Return to user mode */ + NU_USER_MODE(); +} + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/dmce.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,456 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* dmce.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* DM - Dynamic Memory Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the error checking routines for the functions */ +/* in the dynamic memory management component. This permits easy */ +/* removal of the error checking logic when it is not needed. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* DMCE_Create_Memory_Pool Create a dynamic memory pool */ +/* DMCE_Delete_Memory_Pool Delete a dynamic memory pool */ +/* DMCE_Allocate_Memory Allocate a memory block from */ +/* a dynamic memory pool */ +/* DMCE_Deallocate_Memory Deallocate a memory block */ +/* from a dynamic memory pool */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* dm_extr.h Partition functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 11-01-1993 Corrected call of actual */ +/* function to delete a memory */ +/* pool, resulting in version 1.0a */ +/* 11-01-1993 Verfied version 1.0a */ +/* 03-01-1994 Changed name original error */ +/* checking file and changed */ +/* function interfaces, resulting */ +/* in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "dm_extr.h" /* Dynamic memory functions */ + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* DMCE_Create_Memory_Pool */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the create dynamic memory pool function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* DMC_Create_Memory_Pool Actual create dynamic memory */ +/* pool function */ +/* */ +/* INPUTS */ +/* */ +/* pool_ptr Memory pool control block */ +/* pointer */ +/* name Memory pool name */ +/* start_address Starting address of the pool */ +/* pool_size Number of bytes in the pool */ +/* min_allocation Minimum allocation size */ +/* suspend_type Suspension type */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_POOL Indicates the pool control */ +/* block pointer is invalid */ +/* NU_INVALID_MEMORY Indicates the starting */ +/* memory address is NULL */ +/* NU_INVALID_SIZE Indicates that either the */ +/* pool size and/or the */ +/* minimum allocation size is */ +/* invalid */ +/* NU_INVALID_SUSPEND Indicate the suspension type */ +/* is invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS DMCE_Create_Memory_Pool(NU_MEMORY_POOL *pool_ptr, CHAR *name, + VOID *start_address, UNSIGNED pool_size, + UNSIGNED min_allocation, OPTION suspend_type) +{ + +DM_PCB *pool; /* Pool control block ptr */ +STATUS status; /* Completion status */ +UNSIGNED adjusted_min; /* Adjusted size of minimum */ +UNSIGNED adjusted_pool; /* Adjusted size of pool */ + + + /* Move input pool pointer into internal pointer. */ + pool = (DM_PCB *) pool_ptr; + + /* Adjust the minimum allocation size to something that is evenly + divisible by the number of bytes in an UNSIGNED data type. */ + adjusted_min = ((min_allocation + sizeof(UNSIGNED) - 1)/sizeof(UNSIGNED)) * + sizeof(UNSIGNED); + + /* Adjust the pool size to something that is evenly divisible by the + number of bytes in an UNSIGNED data type. */ + adjusted_pool = ((pool_size + sizeof(UNSIGNED) - 1)/sizeof(UNSIGNED)) * + sizeof(UNSIGNED); + + /* Check for a NULL dynamic memory pool control block pointer or a control + block that is already created. */ + if ((pool == NU_NULL) || (pool -> dm_id == DM_DYNAMIC_ID)) + + /* Invalid dynamic memory pool control block pointer. */ + status = NU_INVALID_POOL; + + else if (start_address == NU_NULL) + + /* Invalid memory pointer. */ + status = NU_INVALID_MEMORY; + + else if ((adjusted_min == 0) || + ((adjusted_min + (2 * DM_OVERHEAD)) > adjusted_pool)) + + /* Pool could not even accommodate one allocation. */ + status = NU_INVALID_SIZE; + + else if ((suspend_type != NU_FIFO) && (suspend_type != NU_PRIORITY)) + + /* Invalid suspension type. */ + status = NU_INVALID_SUSPEND; + + else + + /* Call the actual service to create the dynamic memory pool. */ + status = DMC_Create_Memory_Pool(pool_ptr, name, start_address, + pool_size, min_allocation, suspend_type); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* DMCE_Delete_Memory_Pool */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the delete dynamic memory pool function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* DMC_Delete_Memory_Pool Actual function to delete a */ +/* dynamic memory pool */ +/* */ +/* INPUTS */ +/* */ +/* pool_ptr Memory pool control block */ +/* pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_POOL Indicates the pool pointer */ +/* is invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 11-01-1993 Corrected call of actual */ +/* function to delete a memory */ +/* pool, resulting in version 1.0a */ +/* 11-01-1993 Verfied version 1.0a */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS DMCE_Delete_Memory_Pool(NU_MEMORY_POOL *pool_ptr) +{ + +DM_PCB *pool; /* Pool control block ptr */ +STATUS status; /* Completion status */ + + + /* Move input pool pointer into internal pointer. */ + pool = (DM_PCB *) pool_ptr; + + /* Determine if the dynamic memory pool pointer is valid. */ + if ((pool) && (pool -> dm_id == DM_DYNAMIC_ID)) + + /* Dynamic memory pool pointer is valid, call the function to + delete it. */ + status = DMC_Delete_Memory_Pool(pool_ptr); + + else + + /* Dynamic memory pool pointer is invalid, indicate in + completion status. */ + status = NU_INVALID_POOL; + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* DMCE_Allocate_Memory */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the allocate memory function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* DMC_Allocate_Memory Actual memory allocation */ +/* function */ +/* TCCE_Suspend_Error Check for suspension error */ +/* */ +/* INPUTS */ +/* */ +/* pool_ptr Memory pool pointer */ +/* return_pointer Pointer to the destination */ +/* memory pointer */ +/* size Number of bytes requested */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_POOL Indicates the supplied pool */ +/* pointer is invalid */ +/* NU_INVALID_POINTER Indicates the return pointer */ +/* is NULL */ +/* NU_INVALID_SIZE Indicates the size is 0 or */ +/* larger than the pool */ +/* NU_INVALID_SUSPEND Invalid suspension requested */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface , */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS DMCE_Allocate_Memory(NU_MEMORY_POOL *pool_ptr, VOID **return_pointer, + UNSIGNED size, UNSIGNED suspend) +{ + +DM_PCB *pool; /* Pool control block ptr */ +STATUS status; /* Completion status */ + + + /* Move input pool pointer into internal pointer. */ + pool = (DM_PCB *) pool_ptr; + + /* Determine if dynamic memory pool pointer is invalid. */ + if (pool == NU_NULL) + + /* Dynamic memory pool pointer is invalid, indicate in + completion status. */ + status = NU_INVALID_POOL; + + else if (pool -> dm_id != DM_DYNAMIC_ID) + + /* Dynamic memory pool pointer is invalid, indicate in + completion status. */ + status = NU_INVALID_POOL; + + else if (return_pointer == NU_NULL) + + /* Return pointer is invalid. */ + status = NU_INVALID_POINTER; + + else if ((size == 0) || + (size > (pool -> dm_pool_size - (2 * DM_OVERHEAD)))) + + /* Return the invalid size error. */ + status = NU_INVALID_SIZE; + + else if ((suspend) && (TCCE_Suspend_Error())) + + /* Suspension from an non-task thread. */ + status = NU_INVALID_SUSPEND; + + else + + /* Parameters are valid, call actual function. */ + status = DMC_Allocate_Memory(pool_ptr, return_pointer, size, suspend); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* DMCE_Deallocate_Memory */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the deallocate memory function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* DMC_Deallocate_Memory Actual deallocate memory */ +/* function */ +/* */ +/* INPUTS */ +/* */ +/* memory Pointer to dynamic memory */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_POINTER Indicates the supplied */ +/* pointer is invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS DMCE_Deallocate_Memory(VOID *memory) +{ + +DM_PCB *pool; /* Pool pointer */ +DM_HEADER *header_ptr; /* Pointer to memory block */ +STATUS status; /* Completion status */ + + + /* Pickup the associated pool's pointer. It is inside the header of + each memory block. */ + header_ptr = (DM_HEADER *) (((BYTE_PTR) memory) - DM_OVERHEAD); + + /* Determine if the pointer(s) are NULL. */ + if ((header_ptr == NU_NULL) || (memory == NU_NULL)) + + /* Dynamic memory pointer is invalid. */ + status = NU_INVALID_POINTER; + + /* Determine if dynamic memory pool pointer is invalid. */ + else if ((pool = header_ptr -> dm_memory_pool) == NU_NULL) + + /* Dynamic memory pointer is invalid, indicate in completion + status. */ + status = NU_INVALID_POINTER; + + else if (pool -> dm_id != DM_DYNAMIC_ID) + + /* Dynamic memory pool pointer is invalid, indicate in completion + status. */ + status = NU_INVALID_POINTER; + + else if (header_ptr -> dm_memory_free) + + /* Dynamic memory is free - must not be allocated. */ + status = NU_INVALID_POINTER; + + else + + /* Parameters are valid, call actual function. */ + status = DMC_Deallocate_Memory(memory); + + /* Return the completion status. */ + return(status); +} + + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/dmd.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,87 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* dmd.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* DM - Dynamic Memory Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains global data structures for use within the */ +/* Dynamic Memory Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* DMD_Created_Pools Pointer to the linked-list */ +/* of created dynamic pools */ +/* DMD_Total_Pools Total number of created */ +/* dynamic pools */ +/* DMD_List_Protect Dynamic pool list protect */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* dm_defs.h Dynamic memory constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified copyright, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + +#include "dm_defs.h" /* Dynamic memory constants */ + + +/* DMD_Created_Pools_List is the head pointer of the linked list of + created dynamic memory pools. If the list is NU_NULL, there are no + dynamic memory pools created. */ + +CS_NODE *DMD_Created_Pools_List; + + +/* DMD_Total_Pools contains the number of currently created + dynamic memory pools. */ + +UNSIGNED DMD_Total_Pools; + + +/* DMD_List_Protect is a list protection structure used to block any other + thread from access to the created dynamic memory pool list. */ + +TC_PROTECT DMD_List_Protect; + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/dmf.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,384 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* dmf.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* DM - Dynamic Memory Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains routines to obtain facts about the Dynamic */ +/* Memory Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* DMF_Established_Memory_Pools Number of dynamic pools */ +/* DMF_Memory_Pool_Pointers Build memory pool pointer */ +/* list */ +/* DMF_Memory_Pool_Information Retrieve memory pool info */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* dm_extr.h Partition functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Initial version of partition fact */ +/* service file, version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 11-18-1996 Protected Informational service */ +/* from NULL Control Block pointers */ +/* creating 1.2a. (SPR220) */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "dm_extr.h" /* Dynamic memory functions */ +#include "hi_extr.h" /* History functions */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *DMD_Created_Pools_List; +extern UNSIGNED DMD_Total_Pools; +extern TC_PROTECT DMD_List_Protect; + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* DMF_Established_Memory_Pools */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the current number of established */ +/* memory pools. Pools previously deleted are no longer */ +/* considered established. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* DMD_Total_Pools Number of established */ +/* dynamic memory pools */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED DMF_Established_Memory_Pools(VOID) +{ + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Return the number of established dynamic memory pools. */ + return(DMD_Total_Pools); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* DMF_Memory_Pool_Pointers */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function builds a list of pool pointers, starting at */ +/* the specified location. The number of pool pointers */ +/* placed in the list is equivalent to the total number of */ +/* pools or the maximum number of pointers specified in the */ +/* call. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect created list */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* pointer_list Pointer to the list area */ +/* maximum_pointers Maximum number of pointers */ +/* */ +/* OUTPUTS */ +/* */ +/* pointers Number of memory pools */ +/* placed in the list */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected pointer retrieval */ +/* loop, resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED DMF_Memory_Pool_Pointers(NU_MEMORY_POOL **pointer_list, + UNSIGNED maximum_pointers) +{ + +CS_NODE *node_ptr; /* Pointer to each PCB */ +UNSIGNED pointers; /* Number of pointers in list*/ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Initialize the number of pointers returned. */ + pointers = 0; + + /* Protect against access to the list of created memory pools. */ + TCT_Protect(&DMD_List_Protect); + + /* Loop until all pool pointers are in the list or until the maximum + list size is reached. */ + node_ptr = DMD_Created_Pools_List; + while ((node_ptr) && (pointers < maximum_pointers)) + { + + /* Place the node into the destination list. */ + *pointer_list++ = (NU_MEMORY_POOL *) node_ptr; + + /* Increment the pointers variable. */ + pointers++; + + /* Position the node pointer to the next node. */ + node_ptr = node_ptr -> cs_next; + + /* Determine if the pointer is at the head of the list. */ + if (node_ptr == DMD_Created_Pools_List) + + /* The list search is complete. */ + node_ptr = NU_NULL; + } + + /* Release protection of the list of created pools. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the number of pointers in the list. */ + return(pointers); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* DMF_Memory_Pool_Information */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns information about the specified memory */ +/* pool. However, if the supplied memory pool pointer is */ +/* invalid, the function simply returns an error status. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect memory pool */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* pool_ptr Pointer to the memory pool */ +/* name Destination for the name */ +/* start_address Destination for the starting */ +/* memory address of the pool */ +/* pool_size Destination for the pool's */ +/* total size */ +/* min_allocation Destination for the minimum */ +/* block allocation size */ +/* available Destination for the available*/ +/* number of bytes in pool */ +/* suspend_type Destination for the type of */ +/* suspension */ +/* tasks_waiting Destination for the tasks */ +/* waiting count */ +/* first_task Destination for the pointer */ +/* to the first task waiting */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If a valid pool pointer */ +/* is supplied */ +/* NU_INVALID_POOL If pool pointer invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 11-18-1996 Corrected SPR220. */ +/* */ +/*************************************************************************/ +STATUS DMF_Memory_Pool_Information(NU_MEMORY_POOL *pool_ptr, CHAR *name, + VOID **start_address, UNSIGNED *pool_size, + UNSIGNED *min_allocation, UNSIGNED *available, + OPTION *suspend_type, UNSIGNED *tasks_waiting, + NU_TASK **first_task) +{ + +DM_PCB *pool; /* Pool control block ptr */ +INT i; /* Working integer variable */ +STATUS completion; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input pool pointer into internal pointer. */ + pool = (DM_PCB *) pool_ptr; + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Determine if this memory pool id is valid. */ + if ((pool != NU_NULL) && (pool -> dm_id == DM_DYNAMIC_ID)) + { + + /* Setup protection of the memory pool. */ + TCT_Protect(&(pool -> dm_protect)); + + /* The memory pool pointer is valid. Reflect this in the completion + status and fill in the actual information. */ + completion = NU_SUCCESS; + + /* Copy the memory pool's name. */ + for (i = 0; i < NU_MAX_NAME; i++) + *name++ = pool -> dm_name[i]; + + /* Determine the suspension type. */ + if (pool -> dm_fifo_suspend) + *suspend_type = NU_FIFO; + else + *suspend_type = NU_PRIORITY; + + /* Retrieve information directly out of the control structure. */ + *start_address = pool -> dm_start_address; + *pool_size = pool -> dm_pool_size; + *min_allocation = pool -> dm_min_allocation; + *available = pool -> dm_available; + + /* Retrieve the number of tasks waiting and the pointer to the + first task waiting. */ + *tasks_waiting = pool -> dm_tasks_waiting; + if (pool -> dm_suspension_list) + + /* There is a task waiting. */ + *first_task = (NU_TASK *) + (pool -> dm_suspension_list) -> dm_suspended_task; + else + + /* There are no tasks waiting. */ + *first_task = NU_NULL; + + /* Release protection of the memory pool. */ + TCT_Unprotect(); + } + else + + /* Indicate that the memory pool pointer is invalid. */ + completion = NU_INVALID_POOL; + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the appropriate completion status. */ + return(completion); +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/dmi.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,124 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* dmi.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* DM - Dynamic Memory Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the initialization routine for the Dynamic */ +/* Memory Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* DMI_Initialize Dynamic memory initialize */ +/* */ +/* DEPENDENCIES */ +/* */ +/* dm_defs.h Dynamic memory constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified copyright, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "dm_defs.h" /* Dynamic memory constants */ +#include "dm_extr.h" /* Dynamic memory interfaces */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *DMD_Created_Pools_List; +extern UNSIGNED DMD_Total_Pools; +extern TC_PROTECT DMD_List_Protect; + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* DMI_Initialize */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function initializes the data structures that control the */ +/* operation of the Dynamic Memory component (DM). There are no */ +/* dynamic memory pools initially. */ +/* */ +/* CALLED BY */ +/* */ +/* INC_Initialize System initialization */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* DMD_Created_Pools_List List of created pools */ +/* DMD_Total_Pools Number of created pools */ +/* DMD_List_Protect Protection for pool list */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +VOID DMI_Initialize(VOID) +{ + /* Initialize the created dynamic memory pool list to NU_NULL. */ + DMD_Created_Pools_List = NU_NULL; + + /* Initialize the total number of created pools to 0. */ + DMD_Total_Pools = 0; + + /* Initialize the list protection structure. */ + DMD_List_Protect.tc_tcb_pointer = NU_NULL; +} + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/dms.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,425 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* dms.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* DM - Dynamic Memory Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the supplemental routines for the Dynamic */ +/* Memory Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* DMS_Allocate_Aligned_Memory Allocate an aligned memory */ +/* block from a dynamic */ +/* memory pool */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* dm_extr.h Partition functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 01-15-1999 Created initial revision */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "dm_extr.h" /* Dynamic memory functions */ +#include "hi_extr.h" /* History functions */ +#include "profiler.h" /* ProView interface */ + + +/* Define external inner-component global data references. */ + + +/* Define internal component function prototypes. */ +VOID DMC_Cleanup(VOID *information); + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* DMS_Allocate_Aligned_Memory */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function allocates memory from the specified dynamic memory */ +/* pool. If dynamic memory is currently available, this function */ +/* is completed immediately. Otherwise, if there is not enough */ +/* memory currently available, task suspension is possible. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Place on suspend list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Suspend_Task Suspend calling task */ +/* TCC_Task_Priority Pickup task priority */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Current_Thread Pickup current thread pointer*/ +/* TCT_Protect Protect memory pool */ +/* TCT_Set_Suspend_Protect Save suspend protection */ +/* TCT_System_Protect Protect system structures */ +/* TCT_Unprotect Release protection */ +/* TCT_Unprotect_Specific Release specific protection */ +/* */ +/* INPUTS */ +/* */ +/* pool_ptr Memory pool pointer */ +/* return_pointer Pointer to the destination */ +/* memory pointer */ +/* size Number of bytes requested */ +/* alignment Required alignment of */ +/* destination memory pointer */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If service is successful */ +/* NU_NO_MEMORY Memory not available */ +/* NU_TIMEOUT If timeout on service */ +/* NU_POOL_DELETED If memory pool deleted */ +/* during suspension */ +/* */ +/* HISTORY */ +/* */ +/* NAME DATE REMARKS */ +/* */ +/* T. Larsen 01-15-1999 Created initial revision */ +/* R. Baum 06-06-2002 Fixed problem with DM_OVERHEAD */ +/* allocation. Added Proview */ +/* support. */ +/* */ +/*************************************************************************/ +STATUS DMS_Allocate_Aligned_Memory(NU_MEMORY_POOL *pool_ptr, + VOID **return_pointer, UNSIGNED size, + UNSIGNED alignment, UNSIGNED suspend) +{ +R1 DM_PCB *pool; /* Pool control block ptr */ +R2 DM_SUSPEND *suspend_ptr; /* Pointer to suspend block */ +DM_SUSPEND suspend_block; /* Allocate suspension block */ +R4 DM_HEADER *memory_ptr; /* Pointer to memory */ +R3 DM_HEADER *new_ptr; /* New split block pointer */ +UNSIGNED free_size; /* Size of block found */ +TC_TCB *task; /* Task pointer */ +STATUS status; /* Completion status */ +UNSIGNED address; /* Address of start of block */ +UNSIGNED split_size; /* Bytes for front split */ +UNSIGNED next_aligned; /* Next aligned block addr */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input pool pointer into internal pointer. */ + pool = (DM_PCB *) pool_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_ALLOCATE_ALIGNED_ID, (UNSIGNED) pool, + (UNSIGNED) return_pointer, (UNSIGNED) size); + +#endif + + /* Initialize the status as successful. */ + status = NU_SUCCESS; + + /* Adjust the request to a size evenly divisible by the number of bytes + in an UNSIGNED data element. Also, check to make sure it is of the + minimum size. */ + if (size < pool -> dm_min_allocation) + + /* Change size to the minimum allocation. */ + size = pool -> dm_min_allocation; + else + + /* Insure that size is a multiple of the UNSIGNED size. */ + size = + ((size + sizeof(UNSIGNED) - 1)/sizeof(UNSIGNED)) * sizeof(UNSIGNED); + + /* Adjust the requested alignment to one evenly divisible by the number of + bytes in an UNSIGNED data element. */ + alignment = + ((alignment + sizeof(UNSIGNED) - 1)/sizeof(UNSIGNED)) * sizeof(UNSIGNED); + + /* Protect against simultaneous access to the memory pool. */ + TCT_Protect(&(pool -> dm_protect)); + + /* Search the memory list for the first available block of memory that + satisfies the request. Note that blocks are merged during the + deallocation function. */ + memory_ptr = pool -> dm_search_ptr; + do + { + + /* Determine if the block is free and if it can satisfy the request. */ + if (memory_ptr -> dm_memory_free) + + /* Calculate the free block size. */ + free_size = (((BYTE_PTR) (memory_ptr -> dm_next_memory)) - + ((BYTE_PTR) memory_ptr)) - DM_OVERHEAD; + else + + /* There are no free bytes available. */ + free_size = 0; + + /* Free block may be large enough, now check alignment */ + if (free_size >= size) + { + address = ((UNSIGNED)(memory_ptr)) + DM_OVERHEAD; + + /* Is this free block, minus the overhead, already aligned? */ + if (address % alignment != 0) + { + /* Not aligned, can the free block be split in front? */ + next_aligned = address + (alignment - 1); + next_aligned /= alignment; + next_aligned *= alignment; + split_size = next_aligned - address; + + /* Is space from start of block to aligned location large enough + to contain 2 DM_OVERHEAD plus pool -> dm_min_allocation? */ + if (split_size < ((2 * DM_OVERHEAD) + pool -> dm_min_allocation)) + { + /* No, so try to make space for overhead and dm_min_allocation */ + next_aligned = address + (2 * DM_OVERHEAD) + + (pool -> dm_min_allocation) + (alignment - 1); + next_aligned /= alignment; + next_aligned *= alignment; + split_size = next_aligned - address; + } + + /* Adjust free_size for result of front split */ + if (free_size > split_size) + + free_size -= split_size; + + else + + /* Can't adjust block beginning, so keep searching */ + free_size = 0; + } + } + + /* Determine if the search should continue. */ + if (free_size < size) + + /* Large enough block has not been found. Move the search + pointer to the next block. */ + memory_ptr = memory_ptr -> dm_next_memory; + } while((free_size < size) && (memory_ptr != pool -> dm_search_ptr)); + + /* Determine if the memory is available. */ + if (free_size >= size) + { + + /* A block that satisfies the request has been found. */ + + /* Is a front split required? The front split will represent the chunk + of memory that goes from the last pointer to the aligned address. */ + if(address % alignment != 0) + { + /* Not aligned, front split the block, leaving an allocated block. */ + new_ptr = (DM_HEADER*)(((UNSIGNED)(memory_ptr)) + split_size); + + /* Mark the new block as free. */ + new_ptr -> dm_memory_free = NU_TRUE; + + /* Put the pool pointer into the new block. */ + new_ptr -> dm_memory_pool = pool; + + /* Build the necessary pointers. */ + new_ptr -> dm_previous_memory = memory_ptr; + new_ptr -> dm_next_memory = memory_ptr -> dm_next_memory; + (new_ptr -> dm_next_memory) -> dm_previous_memory = new_ptr; + memory_ptr -> dm_next_memory = new_ptr; + + /* Decrement the available byte count by one DM_OVERHEAD. */ + pool -> dm_available = pool -> dm_available - DM_OVERHEAD; + + /* Point to new aligned free block. */ + memory_ptr = new_ptr; + } + + /* Determine if the remaining block needs to be tail split. */ + if (free_size >= (size + DM_OVERHEAD + pool -> dm_min_allocation)) + { + + /* Yes, split the block. */ + new_ptr = (DM_HEADER *) (((BYTE_PTR) memory_ptr) + size + + DM_OVERHEAD); + + /* Mark the new block as free. */ + new_ptr -> dm_memory_free = NU_TRUE; + + /* Put the pool pointer into the new block. */ + new_ptr -> dm_memory_pool = pool; + + /* Build the necessary pointers. */ + new_ptr -> dm_previous_memory = memory_ptr; + new_ptr -> dm_next_memory = memory_ptr -> dm_next_memory; + (new_ptr -> dm_next_memory) -> dm_previous_memory = new_ptr; + memory_ptr -> dm_next_memory = new_ptr; + + /* Decrement the available byte count. */ + pool -> dm_available = pool -> dm_available - size - DM_OVERHEAD; + } + else + + /* Decrement the entire free size from the available bytes + count. */ + pool -> dm_available = pool -> dm_available - free_size; + + /* Mark the allocated block as not available. */ + memory_ptr -> dm_memory_free = NU_FALSE; + + /* Should the search pointer be moved? */ + if (pool -> dm_search_ptr == memory_ptr) + + /* Move the search pointer to the next free memory slot. */ + pool -> dm_search_ptr = memory_ptr -> dm_next_memory; + + /* Return a memory address to the caller. */ + *return_pointer = (VOID *) (((BYTE_PTR) memory_ptr) + DM_OVERHEAD); +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMemoryPool(RT_PROF_ALLOCATE_MEMORY,pool,RT_PROF_OK); +#endif /*INCLUDE_PROVIEW*/ + } + else + { + + /* Enough dynamic memory is not available. Determine if suspension is + required. */ + if (suspend) + { + + /* Suspension is selected. */ + + /* Increment the number of tasks waiting. */ + pool -> dm_tasks_waiting++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMemoryPool(RT_PROF_ALLOCATE_MEMORY,pool,RT_PROF_WAIT); +#endif /*INCLUDE_PROVIEW*/ + /* Setup the suspend block and suspend the calling task. */ + suspend_ptr = &suspend_block; + suspend_ptr -> dm_memory_pool = pool; + suspend_ptr -> dm_request_size = size; + suspend_ptr -> dm_suspend_link.cs_next = NU_NULL; + suspend_ptr -> dm_suspend_link.cs_previous = NU_NULL; + task = (TC_TCB *) TCT_Current_Thread(); + suspend_ptr -> dm_suspended_task = task; + + /* Determine if priority or FIFO suspension is associated with the + memory pool. */ + if (pool -> dm_fifo_suspend) + { + + /* FIFO suspension is required. Link the suspend block into + the list of suspended tasks on this memory pool. */ + CSC_Place_On_List((CS_NODE **) + &(pool -> dm_suspension_list), + &(suspend_ptr -> dm_suspend_link)); + } + else + { + + /* Get the priority of the current thread so the suspend block + can be placed in the appropriate place. */ + suspend_ptr -> dm_suspend_link.cs_priority = + TCC_Task_Priority(task); + + CSC_Priority_Place_On_List((CS_NODE **) + &(pool -> dm_suspension_list), + &(suspend_ptr -> dm_suspend_link)); + } + + /* Protect against system access. */ + TCT_System_Protect(); + + /* Save the list protection in preparation for suspension. */ + TCT_Set_Suspend_Protect(&(pool -> dm_protect)); + + /* Release protection of dynamic memory pool. */ + TCT_Unprotect_Specific(&(pool -> dm_protect)); + + /* Finally, suspend the calling task. Note that the suspension call + automatically clears the system protection. */ + TCC_Suspend_Task((NU_TASK *) task, NU_MEMORY_SUSPEND, + DMC_Cleanup, suspend_ptr, suspend); + + /* Pickup the return status. */ + status = suspend_ptr -> dm_return_status; + *return_pointer = suspend_ptr -> dm_return_pointer; + } + else + { + + /* No suspension requested. Simply return an error status. */ + status = NU_NO_MEMORY; + *return_pointer = NU_NULL; +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMemoryPool(RT_PROF_ALLOCATE_MEMORY,pool,RT_PROF_FAIL); +#endif /*INCLUDE_PROVIEW*/ + } + } + + /* Release protection of the memory pool. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(status); +} + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/er_defs.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,39 @@ + +#ifndef ER_DEFS_H +#define ER_DEFS_H + +#ifdef NU_DEBUG_MEMORY + +/* NU_DEBUG_MEMORY can only service one memory pool each time it is + compiled. It will examine the memory pool NU_DEBUG_POOL points to.*/ +#define NU_DEBUG_POOL System_Memory + +typedef struct ER_DEBUG_ALLOCATION_STRUCT +{ + + /* prev is the link needed to maintain a linked list of all the + ER_DEBUG_ALLOCATION structures. The head of the list is the global + variable ERD_RecentAllocation. */ + struct ER_DEBUG_ALLOCATION_STRUCT *prev; + /* size is the number of bytes used for the users memory allocation */ + unsigned int size; + /* Assignes each allocation an unique ID */ + unsigned long AllocSequenceCounter; + /* line and file refer to the place in the code where the call to the + allocation is made in the application. These variables are filled + in with compiler specific macros. */ + unsigned long line; + const char * file; + /* head and foot contain the non-null terminated strings "HEAD" and + "FOOT" so this module can spot some instances where pointers write + to memory locations beyond thier bounds. data is the user's data + which the allocation call is intended. */ + unsigned char head[4]; + unsigned char data[1]; + +} ER_DEBUG_ALLOCATION; + +#endif /* NU_DEBUG_MEMORY */ + +#endif /* ER_DEFS_H */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/er_extr.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,140 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* er_extr.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* ER - Error Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains function prototypes of all functions */ +/* accessible to other components. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* MACROS */ +/* */ +/* NU_CHECK */ +/* NU_ASSERT */ +/* */ +/* DEPENDENCIES */ +/* */ +/* nucleus.h System definitions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 11-24-1998 Added NU_CHECK and NU_ASSERT. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "nucleus.h" /* Include system definitions */ + + +/* Check to see if the file has been included already. */ + +#ifndef ER_EXTR +#define ER_EXTR + + +/* Initialization function. */ + +VOID ERI_Initialize(VOID); + + +/* System error handling function definition. */ + +VOID ERC_System_Error(INT error_code); + +#ifdef NU_DEBUG_MEMORY + +STATUS ERC_Allocate_Memory(NU_MEMORY_POOL *pool_ptr, VOID **ptr, + UNSIGNED size, UNSIGNED suspend, + unsigned long line, const char* file); + +STATUS ERC_Deallocate_Memory(VOID *ptr); + +#endif /* NU_DEBUG_MEMORY */ + +#ifdef NU_DEBUG + +void ERC_Assert(CHAR *test, CHAR *name, UNSIGNED line); + +#endif + + +#ifdef NU_ASSERT +#undef NU_ASSERT +#endif + + +#ifdef NU_CHECK +#undef NU_CHECK +#endif + + +#ifdef NU_DEBUG + #define NU_ASSERT( test ) \ + if ( !(test) ) ERC_Assert( #test, __FILE__, __LINE__ ); ((void) 0) +#else + #define NU_ASSERT( test ) ((void) 0) +#endif /* NU_DEBUG */ + + +#ifdef NU_DEBUG + #define NU_ASSERT2( test ) \ + if ( !(test) ) ERC_Assert( #test, __FILE__, __LINE__ ); ((void) 0) +#else + #define NU_ASSERT2( test ) ((void) 0) +#endif /* NU_DEBUG */ + + +#ifndef NU_NO_ERROR_CHECKING + #define NU_CHECK( test, statement ) \ + NU_ASSERT2( test ); if ( !(test) ) { statement; } ((void) 0) +#else + #define NU_CHECK( test, statement ) NU_ASSERT2( test ) +#endif /* NU_NO_ERROR_CHECKING */ + + + +#endif + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/erc.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,653 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* erc.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* ER - Error Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the core routines for the Error management */ +/* component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* ERC_System_Error System error function */ +/* ERC_Assert System assertion routine */ +/* */ +/* DEPENDENCIES */ +/* */ +/* tc_defs.h Thread control definitions */ +/* er_extr.h Error handling functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified copyright notice, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 11-24-1998 Added ERC_Assert routine. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-07-1999 Release 1.11mA */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + +#ifdef NU_ERROR_STRING +#include <stdio.h> /* Standard I/O functions */ +#endif +#include "tc_defs.h" /* Thread control constants */ +#include "er_extr.h" /* Error handling functions */ + +#ifdef NU_DEBUG_MEMORY + +#include "er_defs.h" /* Error management structures */ +#include "dm_extr.h" /* Memory management */ +#include "ncl\inc\string.h" /* memcmp & memcpy functions */ +#include "ncl\inc\nu_ncl.h" /* memcmp & memcpy functions */ + +extern NU_MEMORY_POOL NU_DEBUG_POOL; +extern const UINT8 ERD_MemoryAllocationHead[]; +extern const UINT8 ERD_MemoryAllocationFoot[]; +extern ER_DEBUG_ALLOCATION *ERD_RecentAllocation; + +extern UINT32 ERD_AllocationCount; +extern UINT32 ERD_AllocationSequenceCounter; +extern UINT32 ERD_TotalMemoryAllocated; +extern UINT32 ERD_TotalMemoryAllocations; +extern UINT32 ERD_MaxTotalMemoryAllocated; +extern UINT32 ERD_MaxTotalMemoryAllocations; + +#endif /* NU_DEBUG_MEMORY */ + + +/* Define external inner-component global data references. */ + +extern INT ERD_Error_Code; + +#ifdef NU_ERROR_STRING +extern CHAR ERD_Error_String[]; +#endif + +#ifdef NU_DEBUG +extern UNSIGNED ERD_Assert_Count; +#endif + + +/* Define direct access to a thread component variable. */ + +extern VOID *TCD_Current_Thread; + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* ERC_System_Error */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processes system errors detected by various */ +/* system components. Typically an error of this type is */ +/* considered fatal. */ +/* */ +/* CALLED BY */ +/* */ +/* Various Components */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* error_code Code of detected system error*/ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +VOID ERC_System_Error(INT error_code) +{ +#ifdef NU_ERROR_STRING +INT i; +CHAR *pointer; +CHAR name[NU_MAX_NAME+1]; +#endif + +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* First place the error code into the global variable. */ + ERD_Error_Code = error_code; + +#ifdef NU_ERROR_STRING + /* Build string that corresponds to the error. */ + switch(error_code) + { + + case NU_ERROR_CREATING_TIMER_HISR: + + /* Build string that indicates an error occurred creating the timer + HISR. */ + sprintf(ERD_Error_String,"%s\n", "Error Creating Timer HISR"); + break; + + case NU_ERROR_CREATING_TIMER_TASK: + + /* Build string that indicates an error occurred creating the timer + Task. */ + sprintf(ERD_Error_String,"%s\n", "Error Creating Timer Task"); + break; + + case NU_STACK_OVERFLOW: + + /* Build string that indicates a stack overflow occurred. */ + name[NU_MAX_NAME] = (CHAR) 0; + pointer = (((TC_TCB *) TCD_Current_Thread) -> tc_name); + for (i = 0; i < NU_MAX_NAME; i++) + name[i] = *pointer++; + sprintf(ERD_Error_String,"%s %s\n", "Stack Overflow in task/HISR: ", + name); + break; + + + case NU_UNHANDLED_INTERRUPT: + + /* Build string that indicates an error occurred because of an + unhandled interrupt. */ + sprintf(ERD_Error_String,"%s\n", "Unhandled interrupt error"); + break; + } +#endif + + /* This function cannot return, since the error is fatal. */ + while(1) + { + } + + /* No need to return to user mode because of the infinite loop. */ + /* Returning to user mode will cause warnings with some compilers. */ +} + +#ifdef NU_DEBUG_MEMORY + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* ERC_Memory_To_Debug */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns a pointer to the ER_DEBUG_ALLOCATION that */ +/* contains the memory allocation specified by the caller (target). */ +/* */ +/* CALLED BY */ +/* */ +/* ERC_Deallocate_Memory */ +/* */ +/* CALLS */ +/* */ +/* memcmp (CLIB_memcmp) */ +/* ERC_System_Error */ +/* */ +/* INPUTS */ +/* */ +/* target memory allocation to find */ +/* */ +/* OUTPUTS */ +/* */ +/* ER_DEBUG_ALLOCATION ER_DEBUG_ALLOCATION that contains*/ +/* target. */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/*************************************************************************/ +static ER_DEBUG_ALLOCATION *ERC_Memory_To_Debug(VOID *target) +{ + INT dataOffset; + ER_DEBUG_ALLOCATION *walk; + ER_DEBUG_ALLOCATION *to_find; + + dataOffset = (INT)(((ER_DEBUG_ALLOCATION *)0)->data); + to_find = (ER_DEBUG_ALLOCATION *)(((UNSIGNED_CHAR *)target) - dataOffset); + + /* Invalid pointer, report no match found */ + if((target == NULL) && (to_find == NULL)) + return(NULL); + + for (walk = ERD_RecentAllocation; ((walk != to_find) && (walk != NULL)); + walk = walk->prev); + + /* if no match was found */ + if (walk != NULL) + { + /* Has the "HEAD" or "FOOT" been disturbed by a rouge pointer? */ + if (memcmp((void *)ERD_MemoryAllocationHead,(void *)walk->head,4) != 0) + ERC_System_Error(NU_MEMORY_CORRUPT); + if (memcmp((void *)ERD_MemoryAllocationFoot,(void *)&(walk->data[walk->size]),4) != 0) + ERC_System_Error(NU_MEMORY_CORRUPT); + } + + return(walk); +} + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* ERC_Remove_Debug_Allocation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function removes an ER_DEBUG_ALLOCATION from the linked list*/ +/* */ +/* CALLED BY */ +/* */ +/* ERC_Deallocate_Memory */ +/* */ +/* CALLS */ +/* */ +/* none */ +/* */ +/* INPUTS */ +/* */ +/* target ER_DEBUG_ALLOCATION to remove */ +/* */ +/* OUTPUTS */ +/* */ +/* STATUS status of the operation */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/*************************************************************************/ +static STATUS ERC_Remove_Debug_Allocation(ER_DEBUG_ALLOCATION *target) +{ + ER_DEBUG_ALLOCATION *walk; + + if (target == NULL) + return(NU_INVALID_POINTER); + + /* If the list is empty nothing can be removed! */ + if (ERD_RecentAllocation == NULL) + return(NU_EMPTY_DEBUG_ALLOCATION_LIST); + + /* If there is only one item on the list. */ + if (ERD_RecentAllocation->prev == NULL) + { + /* If the only item on the list is the one to be removed...*/ + if (ERD_RecentAllocation == target) + { + ERD_RecentAllocation = NULL; + return(NU_SUCCESS); + } + else + return(NU_INVALID_DEBUG_ALLOCATION); + } + + if (ERD_RecentAllocation == target) + { + ERD_RecentAllocation->prev = target->prev; + return(NU_SUCCESS); + } + + /* Walk the entire list until walk->prev is the target. */ + walk = ERD_RecentAllocation; + while (NU_TRUE) + { + if (walk->prev == target) + break; + if (walk->prev == NULL) + break; + walk = walk->prev; + } + + /* target is last item on the list */ + if (walk->prev == target) + { + walk->prev = target->prev; + return(NU_SUCCESS); + } + return(NU_INVALID_DEBUG_ALLOCATION); +} + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* ERC_Append_Debug_Allocation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function appends an ER_DEBUG_ALLOCATION to the linked list. */ +/* */ +/* CALLED BY */ +/* */ +/* ERC_Allocate_Memory */ +/* */ +/* CALLS */ +/* */ +/* none */ +/* */ +/* INPUTS */ +/* */ +/* new_guy ER_DEBUG_ALLOCATION to append */ +/* */ +/* OUTPUTS */ +/* */ +/* STATUS status of the operation */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/*************************************************************************/ +static STATUS ERC_Append_Debug_Allocation(ER_DEBUG_ALLOCATION *new_guy) +{ + + /* Either this is the first ER_DEBUG_ALLOCATION ever to be appended + or this is the first on a list that shrank to 0 element. */ + if (ERD_AllocationCount == 0) + { + ERD_RecentAllocation = new_guy; + ERD_RecentAllocation->prev = NULL; + } + else + { + new_guy->prev = ERD_RecentAllocation; + ERD_RecentAllocation = new_guy; + } + + return(NU_SUCCESS); +} + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* ERC_Allocate_Memory */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function tracks additional information regarding the memory */ +/* allocation */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* ERC_Append_Debug_Allocation */ +/* DMCE_Allocate_Memory */ +/* memcpy */ +/* */ +/* INPUTS */ +/* */ +/* pool_ptr Memory pool pointer */ +/* return_pointer Pointer to the destination */ +/* memory pointer */ +/* size Number of bytes requested */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If service is successful */ +/* NU_NO_MEMORY Memory not available */ +/* NU_TIMEOUT If timeout on service */ +/* NU_POOL_DELETED If memory pool deleted */ +/* during suspension */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/*************************************************************************/ +STATUS ERC_Allocate_Memory(NU_MEMORY_POOL *pool_ptr, VOID **ptr, + UNSIGNED size, UNSIGNED suspend, + unsigned long line, const char* file) +{ + ER_DEBUG_ALLOCATION **debug_ptr; + STATUS status = NU_SUCCESS; + + /* If the allocation is not from the pool specified in the + NU_DEBUG_POOL macro then allocate memory normally (no meta-data) */ + if(&NU_DEBUG_POOL != pool_ptr) + return(DMCE_Allocate_Memory(pool_ptr, ptr, size, suspend)); + + /* This call allocates memory for a structure that will contain the + users data and the meta-data used to find memory problems */ + status = DMCE_Allocate_Memory(pool_ptr, ptr, + (sizeof(ER_DEBUG_ALLOCATION) + size + 4), suspend); + if (status != NU_SUCCESS) + return status; + + /* From here out, debug_ptr is used because it is typed. In the end + ptr will be set to point to debug_ptr->data, where the user will + put the data. */ + debug_ptr = (ER_DEBUG_ALLOCATION **)ptr; + + /* Record file and line where the application made the allocation */ + (*debug_ptr)->line = line; + (*debug_ptr)->file = file; + + /* Set "HEAD" and "FOOT" boundary markers */ + memcpy((*debug_ptr)->head,ERD_MemoryAllocationHead,4); + memcpy(&((*debug_ptr)->data[size]),ERD_MemoryAllocationFoot,4); + + /* Record the size */ + (*debug_ptr)->size = size; + + /* This links debug_ptr to a linked list that holds all the + ER_DEBUG_ALLOCATION structures. */ + ERC_Append_Debug_Allocation((*debug_ptr)); + + (*debug_ptr)->AllocSequenceCounter = ERD_AllocationSequenceCounter++; + + ERD_TotalMemoryAllocated += size; + ERD_TotalMemoryAllocations++; + ERD_AllocationCount++; + + if (ERD_MaxTotalMemoryAllocated < ERD_TotalMemoryAllocated) + ERD_MaxTotalMemoryAllocated = ERD_TotalMemoryAllocated; + if (ERD_MaxTotalMemoryAllocations < ERD_TotalMemoryAllocations) + ERD_MaxTotalMemoryAllocations = ERD_TotalMemoryAllocations; + + /* Return pointer to the data field of debug allocation by reference */ + (*ptr) = (*debug_ptr)->data; + return(status); +} + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* ERC_Deallocate_Memory */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function tracks additional information regarding the memory */ +/* deallocation. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* ERC_Memory_To_Debug */ +/* ERC_Remove_Debug_Allocation */ +/* DMCE_Deallocate_Memory */ +/* */ +/* INPUTS */ +/* */ +/* ptr Pointer to dynamic memory */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* NU_INVALID_POINTER Returned when ptr is null or */ +/* when there is no */ +/* corresponding */ +/* ER_DEBUG_ALLOCATION */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/*************************************************************************/ +STATUS ERC_Deallocate_Memory(VOID *ptr) +{ + ER_DEBUG_ALLOCATION *target; + STATUS status; + + if (ptr == NULL) + return(NU_INVALID_POINTER); + + /* Find the NU_DEBUG_ALLOCATION ptr refers to. After this call, + (&(target->data) == ptr) or (target == NULL). */ + target = ERC_Memory_To_Debug(ptr); + + /* Remove target from the linked list of ER_DEBUG_ALLOCATIONs */ + status = ERC_Remove_Debug_Allocation(target); + + if ((status != 0) || (target == NULL)) + return(NU_INVALID_POINTER); + + /* Maintain status variables */ + ERD_TotalMemoryAllocated -= target->size; + ERD_TotalMemoryAllocations--; + ERD_AllocationCount--; + + return(DMCE_Deallocate_Memory(target)); +} + +#endif /* NU_DEBUG_MEMORY */ + +/************************************************************************** + This routine should appear last in this file and must *NOT* use the + NU_ASSERT macro. +**************************************************************************/ + +#ifdef NU_ASSERT /* Don't use NU_ASSERT past this point */ +#undef NU_ASSERT +#define NU_ASSERT(ignore) ((void) 0) +#endif + +#ifdef NU_ASSERT2 +#undef NU_ASSERT2 +#define NU_ASSERT2(ignore) ((void) 0) +#endif + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* ERC_Assert */ +/* */ +/* DESCRIPTION */ +/* */ +/* This public routine is called when an assertion made by the */ +/* NU_ASSERT (or NU_ASSERT2) macro fails. By default, this routine */ +/* simply counts the number of failed assertions. A breakpoint can */ +/* be set in the routine to observe failed assertions, or the */ +/* routine can be customized to perform some action, such as */ +/* printing the failed assertion as a message, etc. */ +/* */ +/* CALLED BY */ +/* */ +/* NU_ASSERT macro */ +/* NU_ASSERT2 macro */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* test Pointer to string of failed assertion test */ +/* name File name of file containing failed assertion */ +/* line Location of failed assertion in above file */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* NAME DATE REMARKS */ +/* */ +/* Todd C. Larsen 09-01-1998 Created initial revision */ +/* */ +/*************************************************************************/ +#ifdef NU_DEBUG + +void ERC_Assert(CHAR *test, CHAR *name, UNSIGNED line) +{ +NU_SUPERV_USER_VARIABLES + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_ASSERT_ID, (UNSIGNED) test, + (UNSIGNED) name, line); + +#endif + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Set breakpoint here to catch failed assertions. */ + ERD_Assert_Count += 1; + + /* Return to user mode */ + NU_USER_MODE(); +} + +#endif /* NU_DEBUG */ + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/erd.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,142 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* erd.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* ER - Error Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains global data structures for use within the */ +/* Error Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* ERD_Error_Code Contains the system error */ +/* code */ +/* ERD_Error_String Contains the ASCII system */ +/* error string */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* nucleus.h System definitions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified copyright notice, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 11-24-1998 Added ERD_Assert_Count. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-07-1999 Release 1.11mA */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + +#include "nucleus.h" /* System definitions */ + + +/* ERD_Error_Code contains the system error code detected by the system. */ + +INT ERD_Error_Code; + +#ifdef NU_DEBUG + +/* ERD_Assert_Count contains the number of detected failed assertions. */ +UNSIGNED ERD_Assert_Count; + +#endif + + +#ifdef NU_ERROR_STRING + +/* ERD_Error_String is an area for building an ASCII string representation of + the system error. */ + +CHAR ERD_Error_String[80]; + +#endif + +#ifdef NU_DEBUG_MEMORY + +#include "er_defs.h" + +/* NU_DEBUG_MEMORY wraps the calles to DMCE_Allocate_Memory and + DMCE_Deallocate_Memory with a set of calls that help track memory + problems in a memory pool. The memory pool that will be examined + is determined by the NU_MEMORY_POOL macro. */ + +/* The functions in NU_DEBUG_MEMORY require error checking. + NU_DEBUG_MEMORY can not be defined with NU_NO_ERROR_CHECKING */ + +#ifdef NU_NO_ERROR_CHECKING +#error Can not define NU_DEBUG_MEMORY and NU_NO_ERROR_CHECKING at the same time! +#endif /* NU_NO_ERROR_CHECKING */ + +#ifndef NU_DEBUG +#error NU_DEBUG must be defined when NU_DEBUG_MEMORY is enabled! +#endif /* NU_NO_ERROR_CHECKING */ + +/* ERD_AllocationCount is the current number of sucessful allocations that + have not been deallocated. + ERD_AllocationSequenceCounter identifies each successful allocation by + numbering them in the order they are created. + ERD_TotalMemoryAllocated is the number of sucessful calls to + NU_Allocate_Memory. + ERD_TotalMemoryAllocations is the sum of the sizes of each sucessful + allocation. + ERD_MaxTotalMemoryAllocated is the most memory ever allocated at any + point in time. + ERD_MaxTotalMemoryAllocations is the most outstanding memory allocations + (those that are not deallocated) at any point in time. */ + +UINT32 ERD_AllocationCount; +UINT32 ERD_AllocationSequenceCounter; +UINT32 ERD_TotalMemoryAllocated; +UINT32 ERD_TotalMemoryAllocations; +UINT32 ERD_MaxTotalMemoryAllocated; +UINT32 ERD_MaxTotalMemoryAllocations; + +/* Constants to mark the header and footer */ +const UINT8 ERD_MemoryAllocationHead[] = {'H','E','A','D'}; +const UINT8 ERD_MemoryAllocationFoot[] = {'F','O','O','T'}; + +/* This is the head of a linked list that holds all the currently + outstanding allocations in reverse chronological order. + RED_RecentAllocation is the most recent. The 'prev' field always + points to the allocation made beforehand. */ +ER_DEBUG_ALLOCATION *ERD_RecentAllocation; + +#endif /* NU_DEBUG_MEMORY */ + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/eri.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,156 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* eri.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* ER - Error Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the initialization routine for the Error */ +/* Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* ERI_Initialize Error Management Initialize */ +/* */ +/* DEPENDENCIES */ +/* */ +/* er_extr.h Error management interfaces */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Replaced void with VOID, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-07-1999 Release 1.11mA */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "er_extr.h" /* Error management interfaces */ +#include "er_defs.h" + +/* Define inter-component global data references. */ + +extern INT ERD_Error_Code; + +#ifdef NU_DEBUG_MEMORY + extern UINT32 ERD_AllocationCount; + extern UINT32 ERD_AllocationSequenceCounter; + extern UINT32 ERD_TotalMemoryAllocated; + extern UINT32 ERD_TotalMemoryAllocations; + extern UINT32 ERD_MaxTotalMemoryAllocated; + extern UINT32 ERD_MaxTotalMemoryAllocations; + + extern ER_DEBUG_ALLOCATION *ERD_RecentAllocation; +#endif /* NU_DEBUG_MEMORY */ + +#ifdef NU_DEBUG +extern UNSIGNED ERD_Assert_Count; +#endif + +#ifdef NU_ERROR_STRING +extern CHAR ERD_Error_String[]; +#endif + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* ERI_Initialize */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function initializes the data structures of the Error */ +/* management component (ER). */ +/* */ +/* CALLED BY */ +/* */ +/* INC_Initialize System initialization */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* ERD_Error_Code Contains system error code */ +/* ERD_Error_String ASCII error code string */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Replaced void with VOID, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +VOID ERI_Initialize(VOID) +{ + + /* Clear the system error code flag. */ + ERD_Error_Code = 0; + +#ifdef NU_DEBUG_MEMORY + /* Clear variables that help find memory problems */ + ERD_AllocationCount = 0; + ERD_AllocationSequenceCounter = 0; + ERD_TotalMemoryAllocated = 0; + ERD_TotalMemoryAllocations = 0; + ERD_MaxTotalMemoryAllocated = 0; + ERD_MaxTotalMemoryAllocations = 0; + ERD_RecentAllocation = 0; +#endif /* NU_DEBUG_MEMORY */ + +#ifdef NU_DEBUG + /* Clear count of failed assertions. */ + ERD_Assert_Count = 0; +#endif + +#ifdef NU_ERROR_STRING + /* Make the error string null. */ + ERD_Error_String[0] = 0; +#endif +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/ev_defs.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,117 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* ev_defs.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* EV - Event Group Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains data structure definitions and constants for */ +/* the Event Flag Group component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* EV_GCB Event Group control block */ +/* EV_SUSPEND Event Group suspension block */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_defs.h Common service definitions */ +/* tc_defs.h Thread Control definitions */ +/* */ +/* HISTORY */ +/* */ +/* NAME DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* removed protect structure, */ +/* added padding logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "cs_defs.h" /* Common service constants */ +#include "tc_defs.h" /* Thread control constants */ + + +/* Check to see if the file has been included already. */ + +#ifndef EV_DEFS +#define EV_DEFS + + +/* Define constants local to this component. */ + +#define EV_EVENT_ID 0x45564e54UL +#define EV_AND 0x2 +#define EV_CONSUME 0x1 + + +/* Define the Event Group Control Block data type. */ + +typedef struct EV_GCB_STRUCT +{ + CS_NODE ev_created; /* Node for linking to */ + /* created Events list */ + UNSIGNED ev_id; /* Internal EV ID */ + CHAR ev_name[NU_MAX_NAME]; /* Event group name */ + UNSIGNED ev_current_events; /* Current event flags */ + UNSIGNED ev_tasks_waiting; /* Number of waiting tasks*/ + struct EV_SUSPEND_STRUCT + *ev_suspension_list; /* Suspension list */ +} EV_GCB; + + +/* Define the Event Group suspension structure. This structure is allocated + off of the caller's stack. */ + +typedef struct EV_SUSPEND_STRUCT +{ + CS_NODE ev_suspend_link; /* Link to suspend blocks */ + EV_GCB *ev_event_group; /* Pointer to Event group */ + UNSIGNED ev_requested_events; /* Requested event flags */ + DATA_ELEMENT ev_operation; /* Event operation */ +#if PAD_1 + DATA_ELEMENT ev_padding[PAD_1]; +#endif + TC_TCB *ev_suspended_task; /* Task suspended */ + STATUS ev_return_status; /* Return status */ + UNSIGNED ev_actual_events; /* Event flags returned */ +} EV_SUSPEND; + +#endif + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/ev_extr.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,109 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* ev_extr.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* EV - Event Group Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains function prototypes of all functions */ +/* accessible to other components. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* ev_defs.h Event Flag management consts */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* modified function prototypes, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "ev_defs.h" /* Include EV constants */ + + +/* Check to see if the file has been included already. */ + +#ifndef EV_EXTR +#define EV_EXTR + + +/* Initialization functions. */ + +VOID EVI_Initialize(VOID); + + +/* Error checking functions. */ + +STATUS EVCE_Create_Event_Group(NU_EVENT_GROUP *group_ptr, CHAR *name); +STATUS EVCE_Delete_Event_Group(NU_EVENT_GROUP *group_ptr); +STATUS EVCE_Set_Events(NU_EVENT_GROUP *group_ptr, UNSIGNED events, + OPTION operation); +STATUS EVCE_Retrieve_Events(NU_EVENT_GROUP *group_ptr, + UNSIGNED requested_flags, OPTION operation, + UNSIGNED *retrieved_flags, UNSIGNED suspend); + +/* Core processing functions. */ + + +STATUS EVC_Create_Event_Group(NU_EVENT_GROUP *group_ptr, CHAR *name); +STATUS EVC_Delete_Event_Group(NU_EVENT_GROUP *group_ptr); +STATUS EVC_Set_Events(NU_EVENT_GROUP *group_ptr, UNSIGNED events, + OPTION operation); +STATUS EVC_Retrieve_Events(NU_EVENT_GROUP *group_ptr, + UNSIGNED requested_flags, OPTION operation, + UNSIGNED *retrieved_flags, UNSIGNED suspend); + + +/* Information retrieval functions. */ + +UNSIGNED EVF_Established_Event_Groups(VOID); +STATUS EVF_Event_Group_Information(NU_EVENT_GROUP *group_ptr, + CHAR *name, UNSIGNED *event_flags, + UNSIGNED *tasks_waiting, NU_TASK **first_task); +UNSIGNED EVF_Event_Group_Pointers(NU_EVENT_GROUP **pointer_list, + UNSIGNED maximum_pointers); +#endif + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/evc.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,886 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* evc.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* EV - Event Group Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the core routines for the Event Group */ +/* Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* EVC_Create_Event_Group Create an event group */ +/* EVC_Delete_Event_Group Delete an event group */ +/* EVC_Set_Events Set events in a group */ +/* EVC_Retrieve_Events Retrieve events from a group */ +/* EVC_Cleanup Cleanup on timeout or a */ +/* terminate condition */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* ev_extr.h Event Group functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected pointer retrieval */ +/* loop, resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Moved non-core functions into */ +/* supplemental files, changed */ +/* function interfaces to match */ +/* those in prototype, added */ +/* register options, changed */ +/* protection logic to reduce */ +/* overhead, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 10-28-1997 Corrected a problem where */ +/* NU_Set_Events may not resume all */ +/* waiting tasks. (SPR190) Created */ +/* version 1.2a. */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "ev_extr.h" /* Event Group functions */ +#include "hi_extr.h" /* History functions */ +#include "profiler.h" /* ProView interface */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *EVD_Created_Event_Groups_List; +extern UNSIGNED EVD_Total_Event_Groups; +extern TC_PROTECT EVD_List_Protect; + + +/* Define internal component function prototypes. */ + +VOID EVC_Cleanup(VOID *information); + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* EVC_Create_Event_Group */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function creates an event group and then places it on the */ +/* list of created event groups. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* EVCE_Create_Event_Group Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Add node to linked-list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Data structure protect */ +/* TCT_Unprotect Un-protect data structure */ +/* */ +/* INPUTS */ +/* */ +/* event_group_ptr Event Group control block ptr*/ +/* name Event Group name */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS EVC_Create_Event_Group(NU_EVENT_GROUP *event_group_ptr, CHAR *name) +{ + +R1 EV_GCB *event_group; /* Event control block ptr */ +INT i; /* Working index variable */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input event group pointer into internal pointer. */ + event_group = (EV_GCB *) event_group_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_CREATE_EVENT_GROUP_ID, (UNSIGNED) event_group, + (UNSIGNED) name, (UNSIGNED) 0); + +#endif + + /* First, clear the event group ID just in case it is an old Event Group + Control Block. */ + event_group -> ev_id = 0; + + /* Fill in the event group name. */ + for (i = 0; i < NU_MAX_NAME; i++) + event_group -> ev_name[i] = name[i]; + + /* Clear the flags of the event group. */ + event_group -> ev_current_events = 0; + + /* Clear the suspension list pointer. */ + event_group -> ev_suspension_list = NU_NULL; + + /* Clear the number of tasks waiting on the event_group counter. */ + event_group -> ev_tasks_waiting = 0; + + /* Initialize link pointers. */ + event_group -> ev_created.cs_previous = NU_NULL; + event_group -> ev_created.cs_next = NU_NULL; + + /* Protect against access to the list of created event_groups. */ + TCT_Protect(&EVD_List_Protect); + + /* At this point the event_group is completely built. The ID can now be + set and it can be linked into the created event_group list. */ + event_group -> ev_id = EV_EVENT_ID; + + /* Link the event group into the list of created event groups and + increment the total number of event groups in the system. */ + CSC_Place_On_List(&EVD_Created_Event_Groups_List, + &(event_group -> ev_created)); + EVD_Total_Event_Groups++; +#ifdef INCLUDE_PROVIEW + _RTProf_DumpEventGroup(RT_PROF_CREATE_EVENT_GROUP,event_group, RT_PROF_OK); +#endif /*INCLUDE_PROVIEW*/ + + /* Release protection against access to the list of created event + groups. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* EVC_Delete_Event_Group */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function deletes an event group and removes it from the */ +/* list of created event groups. All tasks suspended on the */ +/* event group are resumed. Note that this function does not */ +/* free the memory associated with the event group control block. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* EVCE_Delete_Event_Group Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove node from list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Protect Protect created list */ +/* TCT_Set_Current_Protect Modify current protection */ +/* TCT_System_Protect Setup system protection */ +/* TCT_System_Unprotect Release system protection */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* event_group_ptr Event Group control block ptr*/ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* NAME DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS EVC_Delete_Event_Group(NU_EVENT_GROUP *event_group_ptr) +{ + +R1 EV_GCB *event_group; /* Event control block ptr */ +EV_SUSPEND *suspend_ptr; /* Suspend block pointer */ +EV_SUSPEND *next_ptr; /* Next suspend block */ +STATUS preempt; /* Status for resume call */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input event group pointer into internal pointer. */ + event_group = (EV_GCB *) event_group_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_DELETE_EVENT_GROUP_ID, (UNSIGNED) event_group, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Protect against simultaneous access to the event group. */ + TCT_System_Protect(); + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpEventGroup(RT_PROF_DELETE_EVENT_GROUP, event_group, RT_PROF_OK); +#endif /*INCLUDE_PROVIEW*/ + + /* Clear the event group ID. */ + event_group -> ev_id = 0; + + /* Release protection. */ + TCT_Unprotect(); + + /* Protect against access to the list of created event groups. */ + TCT_Protect(&EVD_List_Protect); + + /* Remove the event_group from the list of created event groups. */ + CSC_Remove_From_List(&EVD_Created_Event_Groups_List, + &(event_group -> ev_created)); + + /* Decrement the total number of created event groups. */ + EVD_Total_Event_Groups--; + + /* Pickup the suspended task pointer list. */ + suspend_ptr = event_group -> ev_suspension_list; + + /* Walk the chain task(s) currently suspended on the event_group. */ + preempt = 0; + while (suspend_ptr) + { + + /* Protect against system access. */ + TCT_System_Protect(); + + /* Resume the suspended task. Insure that the status returned is + NU_GROUP_DELETED. */ + suspend_ptr -> ev_return_status = NU_GROUP_DELETED; + + /* Point to the next suspend structure in the link. */ + next_ptr = (EV_SUSPEND *) (suspend_ptr -> ev_suspend_link.cs_next); + + /* Resume the specified task. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> ev_suspended_task, + NU_EVENT_SUSPEND); + + /* Determine if the next is the same as the current pointer. */ + if (next_ptr == event_group -> ev_suspension_list) + + /* Clear the suspension pointer to signal the end of the list + traversal. */ + suspend_ptr = NU_NULL; + else + + /* Move the next pointer into the suspend block pointer. */ + suspend_ptr = next_ptr; + + /* Modify current protection. */ + TCT_Set_Current_Protect(&EVD_List_Protect); + + /* Clear the system protection. */ + TCT_System_Unprotect(); + } + + /* Determine if preemption needs to occur. */ + if (preempt) + + /* Transfer control to system to facilitate preemption. */ + TCT_Control_To_System(); + + /* Release protection against access to the list of created + event groups. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return a successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* EVC_Set_Events */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sets event flags within the specified event flag */ +/* group. Event flags may be ANDed or ORed against the current */ +/* events of the group. Any task that is suspended on the group */ +/* that has its request satisfied is resumed. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* EVCE_Set_Events Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove from suspend list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_System_Protect Protect event group */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* event_group_ptr Event Group control block ptr*/ +/* events Event flag setting */ +/* operation Operation to perform on the */ +/* event flag group (AND/OR) */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If service is successful */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 11-19-1996 Corrected SPR190. */ +/* */ +/*************************************************************************/ +STATUS EVC_Set_Events(NU_EVENT_GROUP *event_group_ptr, UNSIGNED events, + OPTION operation) +{ + +R1 EV_GCB *event_group; /* Event control block ptr */ +R2 EV_SUSPEND *suspend_ptr; /* Pointer to suspension blk */ +R3 EV_SUSPEND *next_ptr; /* Pointer to next suspend */ +R4 EV_SUSPEND *last_ptr; /* Last suspension block ptr */ +UNSIGNED consume; /* Event flags to consume */ +UNSIGNED compare; /* Event comparison variable */ +INT preempt; /* Preemption required flag */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input event group pointer into internal pointer. */ + event_group = (EV_GCB *) event_group_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_SET_EVENTS_ID, (UNSIGNED) event_group, + (UNSIGNED) events, (UNSIGNED) operation); + +#endif + + /* Protect against simultaneous access to the event group. */ + TCT_System_Protect(); + + /* Perform the specified operation on the current event flags in the + group. */ + if (operation & EV_AND) + + /* AND the specified events with the current events. */ + event_group -> ev_current_events = + event_group -> ev_current_events & events; + else + + /* OR the specified events with the current events. */ + event_group -> ev_current_events = + event_group -> ev_current_events | events; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpEventGroup(RT_PROF_SET_EVENTS,event_group , RT_PROF_OK); +#endif /*INCLUDE_PROVIEW*/ + /* Determine if there are any tasks suspended for events from this + event flag group. */ + if (event_group -> ev_suspension_list) + { + + /* Initialize the consumption bits to 0. */ + consume = 0; + + /* Now, walk the chain of tasks suspended on this event flag group to + determine if any of their requests can be satisfied. */ + suspend_ptr = event_group -> ev_suspension_list; + + /* Setup a pointer to the last suspension block. */ + last_ptr = (EV_SUSPEND *) suspend_ptr -> ev_suspend_link.cs_previous; + + /* Clear the preempt flag. */ + preempt = 0; + do + { + + /* Determine if this request has been satisfied. */ + + /* First, find the event flags in common. */ + compare = event_group -> ev_current_events & + suspend_ptr -> ev_requested_events; + + /* Second, determine if all the event flags must match. */ + if (suspend_ptr -> ev_operation & EV_AND) + + /* Yes, an AND condition is present. All requested events + must be present. */ + compare = (compare == suspend_ptr -> ev_requested_events); + + /* Setup the next pointer. Note that this must be done before + the suspended task is resumed, since its suspend block could + get corrupted. */ + next_ptr = (EV_SUSPEND *) suspend_ptr -> ev_suspend_link.cs_next; + + /* If compare is non-zero, the suspended task's event request is + satisfied. */ + if (compare) + { + + /* Decrement the number of tasks waiting counter. */ + event_group -> ev_tasks_waiting--; + + /* Determine if consumption is requested. */ + if (suspend_ptr -> ev_operation & EV_CONSUME) + + /* Keep track of the event flags to consume. */ + consume = consume | suspend_ptr -> ev_requested_events; + + /* Remove the first suspended block from the list. */ + CSC_Remove_From_List((CS_NODE **) + &(event_group -> ev_suspension_list), + &(suspend_ptr -> ev_suspend_link)); + + /* Setup the appropriate return value. */ + suspend_ptr -> ev_return_status = NU_SUCCESS; + suspend_ptr -> ev_actual_events = + event_group -> ev_current_events; + + /* Resume the suspended task. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> ev_suspended_task, + NU_EVENT_SUSPEND); + + } + + /* Determine if there is another suspension block to examine. */ + if (suspend_ptr != last_ptr) + + /* More to examine in the suspension list. Look at the + next suspend block. */ + suspend_ptr = next_ptr; + else + + /* End of the list has been reached. Set the suspend pointer + to NULL to end the search. */ + suspend_ptr = NU_NULL; + + } while (suspend_ptr); + + /* Apply all of the gathered consumption bits. */ + event_group -> ev_current_events = + event_group -> ev_current_events & ~consume; + + /* Determine if a preempt condition is present. */ + if (preempt) + + /* Transfer control to the system if the resumed task function + detects a preemption condition. */ + TCT_Control_To_System(); + } + + /* Release protection of the event_group. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return a successful status. */ + return(NU_SUCCESS); +} + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* EVC_Retrieve_Events */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function retrieves various combinations of event flags from */ +/* the specified event group. If the group does not contain the */ +/* necessary flags, suspension of the calling task is possible. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* EVCE_Retrieve_Events Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Place on suspend list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Suspend_Task Suspend calling task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Current_Thread Pickup current thread pointer*/ +/* TCT_System_Protect Protect event group */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* event_group_ptr Event Group control block ptr*/ +/* requested_events Requested event flags */ +/* operation AND/OR selection of flags */ +/* retrieved_events Pointer to destination for */ +/* actual flags retrieved */ +/* suspend Suspension option */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If successful completion */ +/* NU_TIMEOUT If timeout on suspension */ +/* NU_NOT_PRESENT If event flags are not */ +/* present */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS EVC_Retrieve_Events(NU_EVENT_GROUP *event_group_ptr, + UNSIGNED requested_events, OPTION operation, + UNSIGNED *retrieved_events, UNSIGNED suspend) +{ + +R1 EV_GCB *event_group; /* Event control block ptr */ +R2 EV_SUSPEND *suspend_ptr; /* Pointer to suspend block */ +EV_SUSPEND suspend_block; /* Suspension block */ +R3 UNSIGNED compare; /* Event comparison variable */ +TC_TCB *task; /* Pointer to task */ +STATUS status; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input event group pointer into internal pointer. */ + event_group = (EV_GCB *) event_group_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_RETRIEVE_EVENTS_ID, (UNSIGNED) event_group, + (UNSIGNED) requested_events, (UNSIGNED) operation); + +#endif + + /* Initialize the status as successful. */ + status = NU_SUCCESS; + + /* Protect against simultaneous access to the event group. */ + TCT_System_Protect(); + + /* Determine if the events requested are present. */ + + /* Isolate common event flags. */ + compare = event_group -> ev_current_events & requested_events; + + /* Determine if all of the events must be present. */ + if (operation & EV_AND) + + /* Yes, all events must be present. See if the compare value is + the same as the requested value. */ + compare = (compare == requested_events); + + /* Determine if the requested combination of event flags are present. */ + if (compare) + { + + /* Yes, necessary event flags are present. */ + + /* Copy the current event flags into the appropriate destination. */ + *retrieved_events = event_group -> ev_current_events; + + /* Determine if consumption is required. If so, consume the event + flags present in the group. */ + if (operation & EV_CONSUME) + + event_group -> ev_current_events = + event_group -> ev_current_events & ~requested_events; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpEventGroup(RT_PROF_RETRIEVE_EVENTS,event_group, RT_PROF_OK); +#endif /*INCLUDE_PROVIEW*/ + + } + else + { + + /* Determine if the task requested suspension. */ + if (suspend) + { + + /* Suspension is selected. */ + + /* Increment the number of tasks waiting. */ + event_group -> ev_tasks_waiting++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpEventGroup(RT_PROF_RETRIEVE_EVENTS,event_group, RT_PROF_WAIT); +#endif /*INCLUDE_PROVIEW*/ + + /* Setup the suspend block and suspend the calling task. */ + suspend_ptr = &suspend_block; + suspend_ptr -> ev_event_group = event_group; + suspend_ptr -> ev_suspend_link.cs_next = NU_NULL; + suspend_ptr -> ev_suspend_link.cs_previous = NU_NULL; + task = (TC_TCB *) TCT_Current_Thread(); + suspend_ptr -> ev_suspended_task = task; + suspend_ptr -> ev_requested_events = requested_events; + suspend_ptr -> ev_operation = operation; + + /* Link the suspend block into the list of suspended tasks on this + event group. */ + CSC_Place_On_List((CS_NODE **) + &(event_group -> ev_suspension_list), + &(suspend_ptr -> ev_suspend_link)); + + /* Finally, suspend the calling task. Note that the suspension call + automatically clears the protection on the event group. */ + TCC_Suspend_Task((NU_TASK *) task, NU_EVENT_SUSPEND, + EVC_Cleanup, suspend_ptr, suspend); + + /* Pickup the return status and the actual retrieved events. */ + status = suspend_ptr -> ev_return_status; + *retrieved_events = suspend_ptr -> ev_actual_events; + } + else + { + + /* No suspension requested. Simply return an error status + and zero the retrieved events variable. */ + status = NU_NOT_PRESENT; + *retrieved_events = 0; +#ifdef INCLUDE_PROVIEW + _RTProf_DumpEventGroup(RT_PROF_RETRIEVE_EVENTS,event_group,RT_PROF_FAIL); +#endif /*INCLUDE_PROVIEW*/ + } + } + + /* Release protection of the event_group. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* EVC_Cleanup */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for removing a suspension block */ +/* from a event group. It is not called unless a timeout or a task */ +/* terminate is in progress. Note that protection is already in */ +/* effect - the same protection at suspension time. This routine */ +/* must be called from Supervisor mode in Supervisor/User mode */ +/* switching kernels. */ +/* */ +/* CALLED BY */ +/* */ +/* TCC_Timeout Task timeout */ +/* TCC_Terminate Task terminate */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove suspend block from */ +/* the suspension list */ +/* */ +/* INPUTS */ +/* */ +/* information Pointer to suspend block */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +VOID EVC_Cleanup(VOID *information) +{ + +EV_SUSPEND *suspend_ptr; /* Suspension block pointer */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Use the information pointer as a suspend pointer. */ + suspend_ptr = (EV_SUSPEND *) information; + + /* By default, indicate that the service timed-out. It really does not + matter if this function is called from a terminate request since + the task does not resume. */ + suspend_ptr -> ev_return_status = NU_TIMEOUT; + + /* Decrement the number of tasks waiting counter. */ + (suspend_ptr -> ev_event_group) -> ev_tasks_waiting--; + + /* Unlink the suspend block from the suspension list. */ + CSC_Remove_From_List((CS_NODE **) + &((suspend_ptr -> ev_event_group) -> ev_suspension_list), + &(suspend_ptr -> ev_suspend_link)); + + /* Return to user mode */ + NU_USER_MODE(); +} + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/evce.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,393 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* evce.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* EV - Event Group Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the error checking routines for the functions */ +/* in the Event Group component. This permits easy removal of */ +/* error checking logic when it is not needed. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* EVCE_Create_Event_Group Create an event group */ +/* EVCE_Delete_Event_Group Delete an event group */ +/* EVCE_Set_Events Set events in a group */ +/* EVCE_Retrieve_Events Retrieve events from a group */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* ev_extr.h Event Group functions */ +/* */ +/* HISTORY */ +/* */ +/* NAME DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed name original error */ +/* checking file and changed */ +/* function interfaces, resulting */ +/* in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "ev_extr.h" /* Event Group functions */ + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* EVCE_Create_Event_Group */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the create event group function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* EVC_Create_Event_Group Actual create event group */ +/* function */ +/* */ +/* INPUTS */ +/* */ +/* event_group_ptr Event Group control block ptr*/ +/* name Event Group name */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_GROUP Event group control block */ +/* pointer is NULL */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS EVCE_Create_Event_Group(NU_EVENT_GROUP *event_group_ptr, CHAR *name) +{ + +EV_GCB *event_group; /* Event control block ptr */ +STATUS status; /* Completion status */ + + + /* Move input event group pointer into internal pointer. */ + event_group = (EV_GCB *) event_group_ptr; + + /* Check for a NULL event group pointer or an already created event + group. */ + if ((event_group == NU_NULL) || (event_group -> ev_id == EV_EVENT_ID)) + + /* Invalid event group control block pointer. */ + status = NU_INVALID_GROUP; + + else + + /* Call the actual service to create the event group. */ + status = EVC_Create_Event_Group(event_group_ptr, name); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* EVCE_Delete_Event_Group */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the delete event group function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* EVC_Delete_Event_Group Actual delete event group */ +/* function */ +/* */ +/* INPUTS */ +/* */ +/* event_group_ptr Event Group control block ptr*/ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_GROUP Event group control block */ +/* pointer is invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS EVCE_Delete_Event_Group(NU_EVENT_GROUP *event_group_ptr) +{ + +EV_GCB *event_group; /* Event control block ptr */ +STATUS status; /* Completion status */ + + + /* Move input event group pointer into internal pointer. */ + event_group = (EV_GCB *) event_group_ptr; + + /* Determine if the event group pointer is valid. */ + if ((event_group) && (event_group -> ev_id == EV_EVENT_ID)) + + /* Event group pointer is valid, call function to delete it. */ + status = EVC_Delete_Event_Group(event_group_ptr); + + else + + /* Event group pointer is invalid, indicate in completion status. */ + status = NU_INVALID_GROUP; + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* EVCE_Set_Events */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the set events function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* EVC_Set_Events Actual set events function */ +/* */ +/* INPUTS */ +/* */ +/* event_group_ptr Event Group control block ptr*/ +/* events Event flag setting */ +/* operation Operation to perform on the */ +/* event flag group (AND/OR) */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_GROUP Event group control block */ +/* pointer is invalid */ +/* NU_INVALID_OPERATION Event operation is invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS EVCE_Set_Events(NU_EVENT_GROUP *event_group_ptr, UNSIGNED events, + OPTION operation) +{ + +EV_GCB *event_group; /* Event control block ptr */ +STATUS status; /* Completion status */ + + + /* Move input event group pointer into internal pointer. */ + event_group = (EV_GCB *) event_group_ptr; + + /* Determine if event group pointer is invalid. */ + if (event_group == NU_NULL) + + /* Event group pointer is invalid, indicate in completion status. */ + status = NU_INVALID_GROUP; + + else if (event_group -> ev_id != EV_EVENT_ID) + + /* Event group pointer is invalid, indicate in completion status. */ + status = NU_INVALID_GROUP; + + else if ((operation != NU_AND) && (operation != NU_OR)) + + /* Invalid operation on the event flag group. */ + status = NU_INVALID_OPERATION; + + else + + /* Parameters are valid, call actual function. */ + status = EVC_Set_Events(event_group_ptr, events, operation); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* EVCE_Retrieve_Events */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameter supplied */ +/* to the retrieve events function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* EVC_Retrieve_Events Retrieve event flags */ +/* TCCE_Suspend_Error Check for suspend validity */ +/* */ +/* INPUTS */ +/* */ +/* event_group_ptr Event Group control block ptr*/ +/* requested_events Requested event flags */ +/* operation AND/OR selection of flags */ +/* retrieved_events Pointer to destination for */ +/* actual flags retrieved */ +/* suspend Suspension option */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_GROUP Event group control block */ +/* pointer is invalid */ +/* NU_INVALID_POINTER Received event flag pointer */ +/* is NULL */ +/* NU_INVALID_OPERATION Event operation is invalid */ +/* NU_INVALID_SUSPEND Invalid suspension request */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS EVCE_Retrieve_Events(NU_EVENT_GROUP *event_group_ptr, + UNSIGNED requested_events, OPTION operation, + UNSIGNED *retrieved_events, UNSIGNED suspend) +{ + +EV_GCB *event_group; /* Event control block ptr */ +STATUS status; /* Completion status */ + + + /* Move input event group pointer into internal pointer. */ + event_group = (EV_GCB *) event_group_ptr; + + /* Determine if event group pointer is invalid. */ + if (event_group == NU_NULL) + + /* Event group pointer is invalid, indicate in completion status. */ + status = NU_INVALID_GROUP; + + else if (event_group -> ev_id != EV_EVENT_ID) + + /* Event group pointer is invalid, indicate in completion status. */ + status = NU_INVALID_GROUP; + + else if ((operation != NU_AND) && + (operation != NU_AND_CONSUME) && + (operation != NU_OR) && + (operation != NU_OR_CONSUME)) + + /* Invalid operation on the event flag group. */ + status = NU_INVALID_OPERATION; + + else if ((suspend) && (TCCE_Suspend_Error())) + + /* Suspension from an non-task thread. */ + status = NU_INVALID_SUSPEND; + + else if (retrieved_events == NU_NULL) + + /* Retrieved events pointer is NULL. */ + status = NU_INVALID_POINTER; + + else + + /* Parameters are valid, call actual function. */ + status = EVC_Retrieve_Events(event_group_ptr, requested_events, + operation, retrieved_events, suspend); + + /* Return the completion status. */ + return(status); +} + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/evd.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,87 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* evd.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* EV - Event Group Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains global data structures for use within the */ +/* Event Group Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* EVD_Created_Event_Groups_List Pointer to the linked-list */ +/* of created event groups */ +/* EVD_Total_Event_Groups Total number of created */ +/* event groups */ +/* EVD_List_Protect Event Group list protection */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* ev_defs.h Event Group Management const.*/ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified copyright, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + +#include "ev_defs.h" /* Event Group constants */ + + +/* EVD_Created_Event_Groups_List is the head pointer of the linked list of + created event groups. If the list is NU_NULL, there are no event groups + created. */ + +CS_NODE *EVD_Created_Event_Groups_List; + + +/* EVD_Total_Event_Groups contains the number of currently created + event groups. */ + +UNSIGNED EVD_Total_Event_Groups; + + +/* EVD_List_Protect is a list protection structure used to block any other + thread from access to the created event group list. */ + +TC_PROTECT EVD_List_Protect; + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/evf.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,366 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* evf.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* EV - Event Group Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains routines to obtain facts about the Event */ +/* Group Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* EVF_Established_Event_Groups Number of created groups */ +/* EVF_Event_Group_Pointers Build event group pointer */ +/* list */ +/* EVF_Event_Group_Information Retrieve event group info */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* ev_extr.h Event Group functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Initial version of event fact */ +/* service file, version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 11-18-1996 Protected Informational service */ +/* from NULL Control Block pointers */ +/* creating 1.2a. (SPR220) */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "ev_extr.h" /* Event Group functions */ +#include "hi_extr.h" /* History functions */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *EVD_Created_Event_Groups_List; +extern UNSIGNED EVD_Total_Event_Groups; +extern TC_PROTECT EVD_List_Protect; + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* EVF_Established_Event_Groups */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the current number of established */ +/* event groups. Event groups previously deleted are no longer */ +/* considered established. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* EVD_Total_Event_Groups Number of established */ +/* event groups */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED EVF_Established_Event_Groups(VOID) +{ + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Return the number of established event groups. */ + return(EVD_Total_Event_Groups); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* EVF_Event_Group_Pointers */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function builds a list of event group pointers, starting at */ +/* the specified location. The number of event group pointers */ +/* placed in the list is equivalent to the total number of */ +/* event groups or the maximum number of pointers specified in the */ +/* call. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect created list */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* pointer_list Pointer to the list area */ +/* maximum_pointers Maximum number of pointers */ +/* */ +/* OUTPUTS */ +/* */ +/* pointers Number of event groups placed*/ +/* in the list */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected pointer retrieval */ +/* loop, resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED EVF_Event_Group_Pointers(NU_EVENT_GROUP **pointer_list, + UNSIGNED maximum_pointers) +{ +CS_NODE *node_ptr; /* Pointer to each GCB */ +UNSIGNED pointers; /* Number of pointers in list*/ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Initialize the number of pointers returned. */ + pointers = 0; + + /* Protect against access to the list of created event groups. */ + TCT_Protect(&EVD_List_Protect); + + /* Loop until all event group pointers are in the list or until + the maximum list size is reached. */ + node_ptr = EVD_Created_Event_Groups_List; + while ((node_ptr) && (pointers < maximum_pointers)) + { + + /* Place the node into the destination list. */ + *pointer_list++ = (NU_EVENT_GROUP *) node_ptr; + + /* Increment the pointers variable. */ + pointers++; + + /* Position the node pointer to the next node. */ + node_ptr = node_ptr -> cs_next; + + /* Determine if the pointer is at the head of the list. */ + if (node_ptr == EVD_Created_Event_Groups_List) + + /* The list search is complete. */ + node_ptr = NU_NULL; + } + + /* Release protection against access to the list of created + event groups. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the number of pointers in the list. */ + return(pointers); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* EVF_Event_Group_Information */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns information about the specified event */ +/* group. However, if the supplied event group pointer is invalid, */ +/* the function simply returns an error status. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_System_Protect Protect event group */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* event_group_ptr Pointer to the event group */ +/* name Destination for the name */ +/* event_flags Pointer to a variable to hold*/ +/* the current event flags */ +/* tasks_waiting Destination for the tasks */ +/* waiting count */ +/* first_task Destination for the pointer */ +/* to the first task waiting */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If a valid event group */ +/* pointer is supplied */ +/* NU_INVALID_GROUP If event group pointer is */ +/* not valid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 11-18-1996 Corrected SPR220. */ +/* */ +/*************************************************************************/ +STATUS EVF_Event_Group_Information(NU_EVENT_GROUP *event_group_ptr, CHAR *name, + UNSIGNED *event_flags, UNSIGNED *tasks_waiting, NU_TASK **first_task) +{ + +EV_GCB *event_group; /* Event control block ptr */ +INT i; /* Working integer variable */ +STATUS completion; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input event group pointer into internal pointer. */ + event_group = (EV_GCB *) event_group_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Determine if this event_group id is valid. */ + if ((event_group != NU_NULL) && (event_group -> ev_id == EV_EVENT_ID)) + { + + /* Setup protection of the event_group. */ + TCT_System_Protect(); + + /* The event_group pointer is valid. Reflect this in the completion + status and fill in the actual information. */ + completion = NU_SUCCESS; + + /* Copy the event_group's name. */ + for (i = 0; i < NU_MAX_NAME; i++) + *name++ = event_group -> ev_name[i]; + + /* Return the current event flags. */ + *event_flags = event_group -> ev_current_events; + + /* Retrieve the number of tasks waiting and the pointer to the + first task waiting. */ + *tasks_waiting = event_group -> ev_tasks_waiting; + if (event_group -> ev_suspension_list) + + /* There is a task waiting. */ + *first_task = (NU_TASK *) + (event_group -> ev_suspension_list) -> ev_suspended_task; + else + + /* There are no tasks waiting. */ + *first_task = NU_NULL; + + /* Release protection of the event group. */ + TCT_Unprotect(); + } + else + + /* Indicate that the event group pointer is invalid. */ + completion = NU_INVALID_GROUP; + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the appropriate completion status. */ + return(completion); +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/evi.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,135 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* evi.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* EV - Event Group Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the initialization routine for the Event */ +/* Group Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* EVI_Initialize Event Group Management Init */ +/* */ +/* DEPENDENCIES */ +/* */ +/* ev_defs.h Event Group component const. */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified copyright, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "ev_defs.h" /* Event Group constants */ +#include "ev_extr.h" /* Event Group interfaces */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *EVD_Created_Event_Groups_List; +extern UNSIGNED EVD_Total_Event_Groups; +extern TC_PROTECT EVD_List_Protect; + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* EVI_Initialize */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function initializes the data structures that control the */ +/* operation of the Event Group component (EV). There are no */ +/* event groups initially. This routine must be called from */ +/* Supervisor mode in Supervisor/User mode switching kernels. */ +/* */ +/* CALLED BY */ +/* */ +/* INC_Initialize System initialization */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* EVD_Created_Event_Groups_List List of created event groups */ +/* EVD_Total_Event_Groups Number of created event */ +/* groups */ +/* EVD_List_Protect Protection for event group */ +/* list */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +VOID EVI_Initialize(VOID) +{ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Initialize the created event group list to NU_NULL. */ + EVD_Created_Event_Groups_List = NU_NULL; + + /* Initialize the total number of created event groups to 0. */ + EVD_Total_Event_Groups = 0; + + /* Initialize the list protection structure. */ + EVD_List_Protect.tc_tcb_pointer = NU_NULL; + + /* Return to user mode */ + NU_USER_MODE(); +} + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/hi_defs.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,94 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* hi_defs.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* HI - History Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains data structure definitions and constants for */ +/* the History Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* HI_HISTORY_ENTRY Entry in the history table */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* tc_defs.h Thread Control definitions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "tc_defs.h" /* Thread control constants */ + + +/* Check to see if the file has been included already. */ + +#ifndef HI_DEFS +#define HI_DEFS + + +/* Define constants local to this component. */ + +#define HI_MAX_ENTRIES 30 +#define HI_TASK 1 +#define HI_HISR 2 +#define HI_INITIALIZE 3 + + +/* Define the History Entry data type. */ + +typedef struct HI_HISTORY_ENTRY_STRUCT +{ + DATA_ELEMENT hi_id; /* ID of the history entry */ + DATA_ELEMENT hi_caller; /* Task, HISR, or Initialize*/ + UNSIGNED hi_param1; /* First parameter */ + UNSIGNED hi_param2; /* Second parameter */ + UNSIGNED hi_param3; /* Third parameter */ + UNSIGNED hi_time; /* Clock tick time for entry*/ + VOID *hi_thread; /* Calling thread's pointer */ +} HI_HISTORY_ENTRY; + +#endif + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/hi_extr.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,91 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* hi_extr.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* HI - History Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains function prototypes of all functions */ +/* accessible to other components. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* hi_defs.h History Management constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "hi_defs.h" /* Include HI constants */ + + +/* Check to see if the file has been included already. */ + +#ifndef HI_EXTR +#define HI_EXTR + + +/* Initialization functions. */ + +VOID HII_Initialize(VOID); + + +/* Core processing functions. */ + +VOID HIC_Disable_History_Saving(VOID); +VOID HIC_Enable_History_Saving(VOID); +VOID HIC_Make_History_Entry_Service(UNSIGNED param1, + UNSIGNED param2, UNSIGNED param3); +VOID HIC_Make_History_Entry(DATA_ELEMENT id, UNSIGNED param1, + UNSIGNED param2, UNSIGNED param3); +STATUS HIC_Retrieve_History_Entry(DATA_ELEMENT *id, UNSIGNED *param1, + UNSIGNED *param2, UNSIGNED *param3, + UNSIGNED *time, NU_TASK **task, + NU_HISR **hisr); + +#endif + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/hic.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,526 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* hic.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* HI - History Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the core routines for the History Management */ +/* component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* HIC_Disable_History_Saving Disable history saving */ +/* HIC_Enable_History_Saving Enable history saving */ +/* HIC_Make_History_Entry_Service Make history entry service */ +/* HIC_Make_History_Entry Make system history entry */ +/* HIC_Retrieve_History_Entry Retrieve history entry */ +/* */ +/* DEPENDENCIES */ +/* */ +/* tc_extr.h Thread Control functions */ +/* tm_extr.h Timer management functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Replaced void with VOID, */ +/* modified protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + +#include "in_defs.h" /* Initialization defines */ +#include "tc_extr.h" /* Thread control functions */ +#include "tm_extr.h" /* Timer functions */ +#include "hi_extr.h" /* History functions */ + +/* Define external inner-component global data references. */ + +extern INT INC_Initialize_State; +extern INT HID_History_Enable; +extern INT HID_Write_Index; +extern INT HID_Read_Index; +extern INT HID_Entry_Count; +extern TC_PROTECT HID_History_Protect; + + +/* Define the actual history table. Note that this is defined in this file + in order to eliminate this table if none of the run-time history functions + are accessed. */ + +HI_HISTORY_ENTRY HIC_History_Table[HI_MAX_ENTRIES]; + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* HIC_Disable_History_Saving */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function disables the history saving function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCT_Protect Protect history structures */ +/* TCT_Unprotect Release history protection */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Replaced void with VOID, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +VOID HIC_Disable_History_Saving(VOID) +{ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Protect the history data structures. */ + TCT_Protect(&HID_History_Protect); + + /* Disable history saving by setting the enable flag to false. */ + HID_History_Enable = NU_FALSE; + + /* Release protection. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* HIC_Enable_History_Saving */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function enables the history saving function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCT_Protect Protect history structures */ +/* TCT_Unprotect Release history protection */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Replaced void with VOID, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +VOID HIC_Enable_History_Saving(VOID) +{ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Protect the history data structures. */ + TCT_Protect(&HID_History_Protect); + + /* Enable history saving by setting the enable flag to true. */ + HID_History_Enable = NU_TRUE; + + /* Release protection. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* HIC_Make_History_Entry_Service */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function makes an application entry in the history table. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* HIC_Make_History_Entry Make a history entry */ +/* */ +/* INPUTS */ +/* */ +/* param1 First history parameter */ +/* param2 Second history parameter */ +/* param3 Third history parameter */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +VOID HIC_Make_History_Entry_Service(UNSIGNED param1, + UNSIGNED param2, UNSIGNED param3) +{ + /* Call actual function to make the history entry. */ + HIC_Make_History_Entry(NU_USER_ID, param1, param2, param3); +} + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* HIC_Make_History_Entry */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function makes an entry in the next available location in */ +/* the history table- if history saving is enabled. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCC_Current_HISR_Pointer Retrieve current HISR pointer*/ +/* TCC_Current_Task_Pointer Retrieve current task pointer*/ +/* TCT_Get_Current_Protect Pickup current protection */ +/* TCT_Protect Protect history structures */ +/* TCT_Set_Current_Protect Set current protection */ +/* TCT_Unprotect Release history protection */ +/* TCT_Unprotect_Specific Release history protection */ +/* TMT_Retrieve_Clock Retrieve system clock */ +/* */ +/* INPUTS */ +/* */ +/* param1 First history parameter */ +/* param2 Second history parameter */ +/* param3 Third history parameter */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +VOID HIC_Make_History_Entry(DATA_ELEMENT id, UNSIGNED param1, + UNSIGNED param2, UNSIGNED param3) +{ +TC_PROTECT *save_protect; /* Save protect pointer */ +HI_HISTORY_ENTRY *pointer; /* Quick access pointer */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* If we are not in initialization, get the current protection state */ + if (INC_Initialize_State == INC_END_INITIALIZE) + + /* Pickup current protection. */ + save_protect = TCT_Get_Current_Protect(); + + else + /* we are in initialization, just clear save_protect */ + save_protect = 0; + + /* Protect the history data structures. */ + TCT_Protect(&HID_History_Protect); + + /* Determine if history saving is enabled. */ + if (HID_History_Enable) + { + + /* Yes, history saving is enabled. */ + + /* Build a pointer to the next location to write to in the table. */ + pointer = &HIC_History_Table[HID_Write_Index]; + + /* Place the necessary information into the history table at the + current location. */ + pointer -> hi_id = id; + pointer -> hi_param1 = param1; + pointer -> hi_param2 = param2; + pointer -> hi_param3 = param3; + pointer -> hi_time = TMT_Retrieve_Clock(); + + /* Now determine what thread we are currently in. */ + if ((pointer -> hi_thread = + (VOID *) TCC_Current_Task_Pointer()) != NU_NULL) + + /* Task thread. Set the caller flag accordingly. */ + pointer -> hi_caller = HI_TASK; + + else if ((pointer -> hi_thread = + (VOID *) TCC_Current_HISR_Pointer()) != NU_NULL) + + /* HISR thread. Set the caller flag accordingly. */ + pointer -> hi_caller = HI_HISR; + + else + + /* Neither a task or HISR, it caller must be initialization. */ + pointer -> hi_caller = HI_INITIALIZE; + + /* Move the write index. */ + HID_Write_Index++; + + /* Check for a wrap condition on the write index. */ + if (HID_Write_Index >= HI_MAX_ENTRIES) + + /* Wrap condition present, adjust the write index to the top of the + table. */ + HID_Write_Index = 0; + + /* Increment the entries counter, if the maximum has not yet been + reached. */ + if (HID_Entry_Count < HI_MAX_ENTRIES) + + /* Increment the total entries counter. */ + HID_Entry_Count++; + else + + /* Drag the read index along with the write index. */ + HID_Read_Index = HID_Write_Index; + } + + /* Determine if there was protection in force before call. */ + if (save_protect) + { + + /* Make saved protection the current again. */ + TCT_Set_Current_Protect(save_protect); + + /* Release the history protection. */ + TCT_Unprotect_Specific(&HID_History_Protect); + } + else + + /* Release protection. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* HIC_Retrieve_History_Entry */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function retrieves the next oldest entry in the history */ +/* table. If no more entries are available, an error status is */ +/* returned. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCT_Protect Protect history structures */ +/* TCT_Unprotect Release history protection */ +/* */ +/* INPUTS */ +/* */ +/* id Destination for entry id */ +/* param1 Destination for parameter 1 */ +/* param2 Destination for parameter 2 */ +/* param3 Destination for parameter 3 */ +/* time Destination for time of entry*/ +/* task Destination of task pointer */ +/* hisr Destination of hisr pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +STATUS HIC_Retrieve_History_Entry(DATA_ELEMENT *id, UNSIGNED *param1, + UNSIGNED *param2, UNSIGNED *param3, + UNSIGNED *time, NU_TASK **task, + NU_HISR **hisr) +{ + +STATUS status; /* Completion status */ +HI_HISTORY_ENTRY *pointer; /* Quick access pointer */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Initialize status. */ + status = NU_SUCCESS; + + /* Protect the history data structures. */ + TCT_Protect(&HID_History_Protect); + + /* Determine if there is an entry in the history log. */ + if (HID_Entry_Count) + { + + /* Yes, there is at least one entry in the history log. */ + + /* Build a pointer to the next location to read from in the table. */ + pointer = &HIC_History_Table[HID_Read_Index]; + + /* Place the necessary information into the history table at the + current location. */ + *id = pointer -> hi_id; + *param1 = pointer -> hi_param1; + *param2 = pointer -> hi_param2; + *param3 = pointer -> hi_param3; + *time = pointer -> hi_time; + + /* Now determine what thread the entry was made from. */ + if (pointer -> hi_caller == HI_TASK) + { + + /* Setup the task return parameter. */ + *task = (NU_TASK *) pointer -> hi_thread; + *hisr = NU_NULL; + } + else + { + + /* In either HISR or initialize case place the thread value + in the HISR return parameter. */ + *hisr = (NU_HISR *) pointer -> hi_thread; + *task = NU_NULL; + } + + /* Move the read index. */ + HID_Read_Index++; + + /* Check for a wrap condition on the read index. */ + if (HID_Read_Index >= HI_MAX_ENTRIES) + + /* Wrap condition present, adjust the read index to the top of the + table. */ + HID_Read_Index = 0; + + /* Decrement the entries counter. */ + HID_Entry_Count--; + } + else + + /* Return the end of history log status. */ + status = NU_END_OF_LOG; + + /* Release protection. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return completion status to the caller. */ + return(status); +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/hid.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,99 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* hid.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* HI - History Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains global data structures for use within the */ +/* History Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* HID_History_Enable History saving enabled flag */ +/* HID_Write_Index Current write index into */ +/* history table */ +/* HID_Read_Index Current read index into */ +/* history table */ +/* HID_Entry_Count Number of entries in the */ +/* table counter */ +/* HID_History_Protect History protection */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* hi_defs.h History Management constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Updated copyright notice, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + +#include "hi_defs.h" /* History constants */ + + +/* HID_History_Enable is a flag that indicates whether or not history saving + is enabled. If this value is NU_FALSE, history saving is disabled. + Otherwise, history saving is enabled. */ + +INT HID_History_Enable; + + +/* HID_Write_Index is the index of the next available entry in the history + table. */ + +INT HID_Write_Index; + + +/* HID_Read_Index is the index of the oldest entry in the history table. */ + +INT HID_Read_Index; + + +/* HID_Entry_Count keeps track of the number of entries currently + in the history table. */ + +INT HID_Entry_Count; + + +/* HID_History_Protect is a protection structure used to block any other + thread from access to the history data structures. */ + +TC_PROTECT HID_History_Protect; + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/hii.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,135 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* hii.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* HI - History Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the initialization routine for the History */ +/* Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* HII_Initialize History Management Initialize*/ +/* */ +/* DEPENDENCIES */ +/* */ +/* hi_defs.h History component constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Replaced void with VOID, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "hi_defs.h" /* History constants */ +#include "hi_extr.h" /* History interfaces */ + + +/* Define external inner-component global data references. */ + +extern INT HID_History_Enable; +extern INT HID_Write_Index; +extern INT HID_Read_Index; +extern INT HID_Entry_Count; +extern TC_PROTECT HID_History_Protect; + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* HII_Initialize */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function initializes the data structures that control the */ +/* operation of the History component (HI). This routine must be */ +/* called from Supervisor mode in Supervisor/User mode switching */ +/* kernels. */ +/* */ +/* CALLED BY */ +/* */ +/* INC_Initialize System initialization */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* HID_Current_Index Next available table index */ +/* HID_Entry_Count Counter of entries in table */ +/* HID_Table_Protect History table protection */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Replaced void with VOID, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +VOID HII_Initialize(VOID) +{ + /* Initialize the history enable flag to false. */ + HID_History_Enable = NU_FALSE; + + /* Initialize the starting indices to the first entry. */ + HID_Write_Index = 0; + HID_Read_Index = 0; + + /* Initialize the entry counter to 0. */ + HID_Entry_Count = 0; + + /* Initialize the history protection structure. */ + HID_History_Protect.tc_tcb_pointer = NU_NULL; +} + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/in_defs.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,67 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* in_defs.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* IN - Initialization */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains data structure definitions and constants for */ +/* the Initialization component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-20-1998 Created initial version 1.3 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +/* Check to see if the file has been included already. */ + +#ifndef IN_DEFS +#define IN_DEFS + +/* Define constants local to this component. */ + +#define INC_START_INITIALIZE 1 +#define INC_END_INITIALIZE 2 + + +#endif /* IN_DEFS */ + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/in_extr.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,86 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* in_extr.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* IN - Initialization */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains function prototypes of all functions */ +/* accessible to other components. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* nucleus.h Nucleus PLUS definitions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "nucleus.h" /* Include system constants */ + + +/* Check to see if the file has been included already. */ + +#ifndef IN_EXTR +#define IN_EXTR + + +VOID INT_Initialize(VOID); +VOID INC_Initialize(VOID *first_available_memory); + +/* Depending on the target processor, these routines may only be callable + successfully from Supervisor mode in Supervisor/User mode switching + kernels. If this is the case, SUC_ versions of these routines will be + available for calling from User mode. +*/ +VOID *INT_Retrieve_Shell(INT vector); +VOID *INT_Setup_Vector(INT vector, VOID *pointer); +INT INT_Vectors_Loaded(VOID); + +#endif /* IN_EXTR */ + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/inc.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,234 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* inc.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* IN - Initialization */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains initialization and setup routines associated */ +/* with the initialization component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* INC_Initialize Common system initialization */ +/* */ +/* DEPENDENCIES */ +/* */ +/* in_extr.h Initialization functions */ +/* er_extr.h Error handling function */ +/* hi_extr.h History functions */ +/* tc_extr.h Thread Control functions */ +/* mb_extr.h Mailbox functions */ +/* qu_extr.h Queue functions */ +/* pi_extr.h Pipe functions */ +/* sm_extr.h Semaphore functions */ +/* ev_extr.h Event group functions */ +/* pm_extr.h Partition memory functions */ +/* dm_extr.h Dynamic memory functions */ +/* tm_extr.h Timer functions */ +/* io_extr.h I/O Driver functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Replaced void with VOID, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-20-1998 Moved the INC_Initialize_State */ +/* define values into their own */ +/* in_defs.h include file as part */ +/* of SPR455. This creates */ +/* version 1.2a. */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "in_defs.h" /* Initialization defines */ +#include "in_extr.h" /* Initialization functions */ +#include "hi_extr.h" /* History functions */ +#include "er_extr.h" /* Error handling function */ +#include "tc_extr.h" /* Thread Control functions */ +#include "mb_extr.h" /* Mailbox functions */ +#include "qu_extr.h" /* Queue functions */ +#include "pi_extr.h" /* Pipe functions */ +#include "sm_extr.h" /* Semaphore functions */ +#include "ev_extr.h" /* Event group functions */ +#include "pm_extr.h" /* Partition memory functions*/ +#include "dm_extr.h" /* Dynamic memory functions */ +#include "tm_extr.h" /* Timer functions */ +#include "io_extr.h" /* I/O Driver functions */ + + +/* Define global variable that contains the state of initialization. This + flag is for information use only. */ + +INT INC_Initialize_State; + + +/* Define external functions that access the release and license + information. */ + +CHAR *RLC_Release_Information(VOID); +CHAR *LIC_License_Information(VOID); + +#if defined(NU_MODULE_SUPPORT) && (NU_MODULE_SUPPORT > 0) + +/* Prototypes for Module Initialization funcitons */ +STATUS MRC_Initialize(VOID); +STATUS MSC_Initialize(VOID); + +#endif + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* INC_Initialize */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is the main initialization function of the system. */ +/* All components are initialized by this function. After system */ +/* initialization is complete, the Application_Initialize routine */ +/* is called. After all initialization is complete, this function */ +/* calls TCT_Schedule to start scheduling tasks. */ +/* */ +/* CALLED BY */ +/* */ +/* INT_Initialize Target dependent initialize */ +/* */ +/* CALLS */ +/* */ +/* Application_Initialize Application initialize */ +/* RLC_Release_Information Release information */ +/* LIC_License_Information License information */ +/* ERI_Initialize Error handling initialize */ +/* HII_Initialize History initialization */ +/* TCI_Initialize Thread control initialize */ +/* MBI_Initialize Mailbox initialize */ +/* QUI_Initialize Queue initialize */ +/* PII_Initialize Pipe initialize */ +/* SMI_Initialize Semaphore initialize */ +/* EVI_Initialize Event flag initialize */ +/* PMI_Initialize Partition memory initialize */ +/* DMI_Initialize Dynamic memory initialize */ +/* TMI_Initialize Timer initialize */ +/* IOI_Initialize I/O Driver initialize */ +/* MRC_Initialize Memory Region initialize */ +/* MSC_Initialize Module Support initialize */ +/* TCT_Schedule Thread scheduling loop */ +/* */ +/* INPUTS */ +/* */ +/* first_available_memory Pointer to available memory */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +VOID INC_Initialize(VOID *first_available_memory) +{ + + /* Indicate that initialization is starting. */ + INC_Initialize_State = INC_START_INITIALIZE; + + /* Call release information function. */ + RLC_Release_Information(); + + /* Call license information function. */ + LIC_License_Information(); + + /* Initialize the Error handling (ER) component. */ + ERI_Initialize(); + + /* Initialize the History (HI) component. */ + HII_Initialize(); + +#if defined(NU_MODULE_SUPPORT) && (NU_MODULE_SUPPORT > 0) + + MRC_Initialize(); /* Initialize Memory Region component */ + MSC_Initialize(); /* Initialize Module Support component */ + +#endif + + /* Initialize the Thread Control (TC) component. */ + TCI_Initialize(); + + /* Initialize the Mailbox (MB) component. */ + MBI_Initialize(); + + /* Initialize the Queue (QU) component. */ + QUI_Initialize(); + + /* Initialize the Pipe (PI) component. */ + PII_Initialize(); + + /* Initialize the Semaphore (SM) component. */ + SMI_Initialize(); + + /* Initialize the Event Group (EV) component. */ + EVI_Initialize(); + + /* Initialize the Partition memory (PM) component. */ + PMI_Initialize(); + + /* Initialize the Dynamic memory (DM) component. */ + DMI_Initialize(); + + /* Initialize the Timer (TM) component. */ + TMI_Initialize(); + + /* Initialize the I/O Driver (IO) component. */ + IOI_Initialize(); + + /* Invoke the application-supplied initialization function. */ + Application_Initialize(first_available_memory); + + /* Indicate that initialization is finished. */ + INC_Initialize_State = INC_END_INITIALIZE; + + /* Start scheduling threads of execution. */ + TCT_Schedule(); +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/io_defs.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,75 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* io_defs.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* IO - Input/Output Driver Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains data structure definitions and constants for */ +/* the Input/Output Driver component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +/* Check to see if the file has been included already. */ + +#ifndef IO_DEFS +#define IO_DEFS + + +/* Define constants local to this component. */ + +#define IO_DRIVER_ID 0x494f4452UL + + +#endif + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/io_extr.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,111 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* io_extr.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* IO - Input/Output Driver Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains function prototypes of all functions */ +/* accessible to other components. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* io_defs.h I/O Driver Management consts */ +/* tc_defs.h Thread control constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* changed function interfaces, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "io_defs.h" /* Include IO constants */ +#include "tc_defs.h" /* Thread control constants */ + + +/* Check to see if the file has been included already. */ + +#ifndef IO_EXTR +#define IO_EXTR + + +/* Initialization functions. */ + +VOID IOI_Initialize(VOID); + + +/* Error checking functions. */ + +STATUS IOCE_Create_Driver(NU_DRIVER *driver, CHAR *name, + VOID (*driver_entry)(NU_DRIVER *, NU_DRIVER_REQUEST *)); +STATUS IOCE_Delete_Driver(NU_DRIVER *driver); +STATUS IOCE_Request_Driver(NU_DRIVER *driver, + NU_DRIVER_REQUEST *request); +STATUS IOCE_Resume_Driver(NU_TASK *task); +STATUS IOCE_Suspend_Driver(VOID (*terminate_routine)(VOID *), + VOID *information, UNSIGNED timeout); + + +/* Core processing functions. */ + +STATUS IOC_Create_Driver(NU_DRIVER *driver, CHAR *name, + VOID (*driver_entry)(NU_DRIVER *, NU_DRIVER_REQUEST *)); +STATUS IOC_Delete_Driver(NU_DRIVER *driver); +STATUS IOC_Request_Driver(NU_DRIVER *driver, + NU_DRIVER_REQUEST *request); +STATUS IOC_Resume_Driver(NU_TASK *task); +STATUS IOC_Suspend_Driver(VOID (*terminate_routine)(VOID *), + VOID *information, UNSIGNED timeout); + + +/* Information retrieval functions. */ + +UNSIGNED IOF_Established_Drivers(VOID); +UNSIGNED IOF_Driver_Pointers(NU_DRIVER **pointer_list, + UNSIGNED maximum_pointers); + +#endif + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/ioc.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,606 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* ioc.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* IO - Input/Output Driver Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the core routines for the I/O Driver */ +/* Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* IOC_Create_Driver Create an I/O driver */ +/* IOC_Delete_Driver Delete an I/O driver */ +/* IOC_Request_Driver Make an I/O driver request */ +/* IOC_Resume_Driver Resume a task suspended in */ +/* an I/O driver */ +/* IOC_Suspend_Driver Suspend a task inside an I/O */ +/* driver */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* io_extr.h I/O driver functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected pointer retrieval */ +/* loop, resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Moved non-core functions into */ +/* supplemental files, changed */ +/* function interfaces to match */ +/* those in prototype, changed */ +/* protection logic to reduce */ +/* overhead, resulting in */ +/* version 1.1 */ +/* */ +/* 03-15-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 04-23-1996 Corrected SPR121. */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-07-1999 Release 1.11mA */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "io_extr.h" /* I/O driver functions */ +#include "hi_extr.h" /* History functions */ +#include "profiler.h" /* ProView interface */ + +/* Define external inner-component global data references. */ + +extern CS_NODE *IOD_Created_Drivers_List; +extern UNSIGNED IOD_Total_Drivers; +extern TC_PROTECT IOD_List_Protect; + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* IOC_Create_Driver */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function creates an I/O driver and places it on the list of */ +/* created I/O drivers. Note that this function does not actually */ +/* invoke the driver. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* IOCE_Create_Driver Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Add node to linked-list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Data structure protect */ +/* TCT_Unprotect Un-protect data structure */ +/* */ +/* INPUTS */ +/* */ +/* driver Driver control block pointer */ +/* name Driver's logical name */ +/* driver_entry Driver's point of entry */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +STATUS IOC_Create_Driver(NU_DRIVER *driver, CHAR *name, + VOID (*driver_entry)(NU_DRIVER *, NU_DRIVER_REQUEST *)) +{ + +INT i; /* Working index variable */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_CREATE_DRIVER_ID, (UNSIGNED) driver, + (UNSIGNED) name, (UNSIGNED) driver_entry); + +#endif + + /* First, clear the driver ID just in case it is an old Driver + Control Block. */ + driver -> nu_driver_id = 0; + + /* Fill in the driver's name. */ + for (i = 0; i < NU_MAX_NAME; i++) + driver -> nu_driver_name[i] = name[i]; + + /* Save the driver's entry function in the control block. */ + driver -> nu_driver_entry = driver_entry; + + /* Protect against access to the list of created drivers. */ + TCT_Protect(&IOD_List_Protect); + + /* At this point the driver is completely built. The ID can now be + set and it can be linked into the created driver list. */ + driver -> nu_driver_id = IO_DRIVER_ID; + + /* Link the driver into the list of created I/O drivers and increment the + total number of drivers in the system. */ + CSC_Place_On_List(&IOD_Created_Drivers_List, (CS_NODE *) driver); + IOD_Total_Drivers++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpDriver(RT_PROF_CREATE_DRIVER, driver, RT_PROF_OK); +#endif /*INCLUDE_PROVIEW*/ + /* Release protection against access to the list of created I/O drivers. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* IOC_Delete_Driver */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function deletes an I/O driver and removes it from the list */ +/* of created drivers. Note that this function does not actually */ +/* invoke the driver. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* IOCE_Delete_Driver Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove node from list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect created list */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* driver Driver control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +STATUS IOC_Delete_Driver(NU_DRIVER *driver) +{ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_DELETE_DRIVER_ID, (UNSIGNED) driver , + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Protect against access to the list of created I/O drivers. */ + TCT_Protect(&IOD_List_Protect); + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpDriver(RT_PROF_DELETE_DRIVER, driver, RT_PROF_OK); +#endif /*INCLUDE_PROVIEW*/ + /* Set the driver ID to 0. */ + driver -> nu_driver_id = 0; + + /* Remove the driver from the list of created I/O drivers. */ + CSC_Remove_From_List(&IOD_Created_Drivers_List, (CS_NODE *) driver); + + /* Decrement the total number of created I/O drivers. */ + IOD_Total_Drivers--; + + /* Release protection against access to the list of created I/O drivers. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return a successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* IOC_Request_Driver */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sends a user request to the specified I/O driver. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* IOCE_Request_Driver Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* [TCT_Check_Stack] Stack checking function */ +/* */ +/* INPUTS */ +/* */ +/* driver Driver control block pointer */ +/* request User's I/O request */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If service is successful */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +STATUS IOC_Request_Driver(NU_DRIVER *driver , NU_DRIVER_REQUEST *request) +{ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_REQUEST_DRIVER_ID, (UNSIGNED) driver, + (UNSIGNED) request, (UNSIGNED) 0); + +#endif + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpDriver(RT_PROF_REQUEST_DRIVER, driver, RT_PROF_OK); +#endif /*INCLUDE_PROVIEW*/ + /* Call the specified I/O Driver. */ + (*(driver -> nu_driver_entry)) (driver, request); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* IOC_Resume_Driver */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function resumes a task previously suspended inside of an */ +/* I/O driver. Typically, this function is called from within an */ +/* I/O driver. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* IOCE_Resume_Driver Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* TCT_Control_To_System Transfer control to higher */ +/* priority task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Get_Current_Protect Pickup current protection */ +/* TCT_Set_Current_Protect Set current protection */ +/* TCT_System_Protect Protect against system access*/ +/* TCT_System_Unprotect Release system protection */ +/* TCT_Unprotect Release system protection */ +/* TCT_Unprotect_Specific Release specific protection */ +/* */ +/* INPUTS */ +/* */ +/* task Pointer of task to resume */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If service is successful */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match prototype, changed */ +/* protection logic, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-23-1996 Corrected SPR121 */ +/* */ +/*************************************************************************/ +STATUS IOC_Resume_Driver(NU_TASK *task) +{ + +TC_PROTECT *save_protect; /* Saved protect pointer */ +NU_SUPERV_USER_VARIABLES + + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_RESUME_DRIVER_ID, (UNSIGNED) task, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Pickup current protection. */ + save_protect = TCT_Get_Current_Protect(); + + /* Protect against system access. */ + TCT_System_Protect(); + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpDriver(RT_PROF_RESUME_DRIVER, 0 , RT_PROF_OK); +#endif /*INCLUDE_PROVIEW*/ + /* Resume the specified task. */ + if (TCC_Resume_Task(task, NU_DRIVER_SUSPEND)) + { + /* Only unprotect if there is protection in place. */ + if (save_protect) + { + /* Release protection caller had. */ + TCT_Unprotect_Specific(save_protect); + } + + /* Transfer control to the system if the resumed task function + detects a preemption condition. */ + TCT_Control_To_System(); + } + else + { + + /* Determine if there was protection previously in force. */ + if (save_protect) + { + + /* Switch to original protection. */ + TCT_Set_Current_Protect(save_protect); + + /* Release system protection. */ + TCT_System_Unprotect(); + } + else + + /* Release system protection. */ + TCT_Unprotect(); + } + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(NU_SUCCESS); +} + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* IOC_Suspend_Driver */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function suspends a task inside of an I/O driver. It is */ +/* the responsibility of the I/O driver to keep track of tasks */ +/* waiting inside of an I/O driver. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* IOCE_Suspend_Driver Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Suspend_Task Suspend calling task */ +/* TCT_Current_Thread Current task thread */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Get_Current_Protect Pickup current protect ptr */ +/* TCT_Set_Suspend_Protect Setup suspend protect field */ +/* TCT_System_Protect Protect against system access*/ +/* TCT_Unprotect_Specific Release user protection */ +/* */ +/* INPUTS */ +/* */ +/* terminate_routine Termination/Timeout cleanup */ +/* routine */ +/* information Information pointer of the */ +/* cleanup routine */ +/* timeout Suspension timeout request */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If service is successful */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-23-1996 Corrected SPR121. */ +/* */ +/*************************************************************************/ +STATUS IOC_Suspend_Driver(VOID (*terminate_routine)(VOID *), + VOID *information, UNSIGNED timeout) +{ + +TC_PROTECT *suspend_protect; /* Current protection */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_SUSPEND_DRIVER_ID, (UNSIGNED) terminate_routine, + (UNSIGNED) information, (UNSIGNED) timeout); + +#endif + + + /* Pickup current protect. */ + suspend_protect = TCT_Get_Current_Protect(); + + /* Setup system protection. */ + TCT_System_Protect(); + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpDriver(RT_PROF_SUSPEND_DRIVER, 0 , RT_PROF_OK); +#endif /*INCLUDE_PROVIEW*/ + /* If no protection exists, don't unprotect. */ + if (suspend_protect) + { + /* Release initial protection. */ + TCT_Unprotect_Specific(suspend_protect); + + /* Save suspend protect for timeout and terminate. */ + TCT_Set_Suspend_Protect(suspend_protect); + } + + /* Suspend the calling task. */ + TCC_Suspend_Task((NU_TASK *) TCT_Current_Thread(), NU_DRIVER_SUSPEND, + terminate_routine, information, timeout); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(NU_SUCCESS); +} + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/ioce.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,440 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* ioce.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* IO - Input/Output Driver Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the error checking routines for the functions */ +/* in the Input/Output Driver component. This permits easy removal */ +/* of error checking logic when it is not needed. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* IOCE_Create_Driver Create an I/O driver */ +/* IOCE_Delete_Driver Delete an I/O driver */ +/* IOCE_Request_Driver Make an I/O driver request */ +/* IOCE_Resume_Driver Resume a task suspended in */ +/* an I/O driver */ +/* IOCE_Suspend_Driver Suspend a task inside an I/O */ +/* driver */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* io_extr.h I/O driver functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified logic that checked task */ +/* status without protection of */ +/* scheduling structures, */ +/* resulting in version 1.0a */ +/* 03-01-1994 Verified version 1.0a */ +/* 03-01-1994 Changed name original error */ +/* checking file and changed */ +/* function interfaces, resulting */ +/* in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "io_extr.h" /* I/O driver functions */ +#include "hi_extr.h" /* History functions */ + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* IOCE_Create_Driver */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the I/O driver create function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* IOC_Create_Driver Actual create driver routine */ +/* */ +/* INPUTS */ +/* */ +/* driver Driver control block pointer */ +/* name Driver's logical name */ +/* driver_entry Driver's point of entry */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_DRIVER Indicates driver pointer is */ +/* NULL or is already in use */ +/* NU_INVALID_POINTER Indicates the driver's entry */ +/* pointer is NULL */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS IOCE_Create_Driver(NU_DRIVER *driver, CHAR *name, + VOID (*driver_entry)(NU_DRIVER *, NU_DRIVER_REQUEST *)) +{ + +STATUS status; /* Completion status */ + + + /* Check for an invalid driver pointer. */ + if ((driver == NU_NULL) || (driver -> nu_driver_id == IO_DRIVER_ID)) + + /* Indicate that the driver pointer is invalid. */ + status = NU_INVALID_DRIVER; + + else if (driver_entry == NU_NULL) + + /* Indicate that the driver entry point is invalid. */ + status = NU_INVALID_POINTER; + + else + + /* Parameters are okay, call actual function to create an I/O + driver. */ + status = IOC_Create_Driver(driver, name, driver_entry); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* IOCE_Delete_Driver */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the I/O driver delete function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* IOC_Delete_Driver Actual delete driver routine */ +/* */ +/* INPUTS */ +/* */ +/* driver Driver control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_DRIVER Indicates the driver pointer */ +/* is invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS IOCE_Delete_Driver(NU_DRIVER *driver) +{ + +STATUS status; /* Completion status */ + + /* Determine if the driver pointer is valid. */ + if ((driver) && (driver -> nu_driver_id == IO_DRIVER_ID)) + + /* Driver pointer is valid, call function to delete it. */ + status = IOC_Delete_Driver(driver); + + else + + /* Driver pointer is invalid, indicate in completion status. */ + status = NU_INVALID_DRIVER; + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* IOCE_Request_Driver */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the I/O driver request function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* IOC_Request_Driver Actual request driver routine*/ +/* */ +/* INPUTS */ +/* */ +/* driver Driver control block pointer */ +/* request User's I/O request */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_DRIVER Indicates the driver pointer */ +/* is invalid */ +/* NU_INVALID_POINTER Indicates the request pointer*/ +/* is invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS IOCE_Request_Driver(NU_DRIVER *driver , NU_DRIVER_REQUEST *request) +{ + +STATUS status; /* Completion status */ + + + /* Determine if driver pointer is invalid. */ + if (driver == NU_NULL) + + /* Driver pointer is invalid, indicate in completion status. */ + status = NU_INVALID_DRIVER; + + else if (driver -> nu_driver_id != IO_DRIVER_ID) + + /* Driver pointer is invalid, indicate in completion status. */ + status = NU_INVALID_DRIVER; + + else if (request == NU_NULL) + + /* Request pointer is invalid, indicate in completion status. */ + status = NU_INVALID_POINTER; + + else + + /* Parameters are valid, call actual function. */ + status = IOC_Request_Driver(driver, request); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* IOCE_Resume_Driver */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the I/O driver resume function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCCE_Validate_Resume Validate resume driver */ +/* request against actual */ +/* status */ +/* IOC_Resume_Driver Actual resume driver routine */ +/* */ +/* INPUTS */ +/* */ +/* task Pointer of task to resume */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_TASK Indicates the task pointer */ +/* is invalid */ +/* NU_INVALID_RESUME Indicates the task is not */ +/* suspended */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified logic that checked task */ +/* status without protection of */ +/* scheduling structures, */ +/* resulting in version 1.0a */ +/* 03-01-1994 Verified version 1.0a */ +/* 03-01-1994 Changed function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS IOCE_Resume_Driver(NU_TASK *task) +{ + +STATUS status; /* Completion status */ + + + /* Determine if the task pointer is valid. */ + if ((task == NU_NULL) || (((TC_TCB *) task) -> tc_id != TC_TASK_ID)) + + /* Task pointer is invalid. */ + status = NU_INVALID_TASK; + + /* Check actual status of task to see if request is valid. */ + else if (TCCE_Validate_Resume(NU_DRIVER_SUSPEND, task)) + + /* Task is not suspended in a driver, return error status. */ + status = NU_INVALID_RESUME; + + else + + /* Call the actual resume service. */ + status = IOC_Resume_Driver(task); + + /* Return the completion status. */ + return(status); +} + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* IOCE_Suspend_Driver */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the I/O driver suspend function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* IOC_Suspend_Driver Actual driver suspend routine*/ +/* TCCE_Suspend_Error Check for a legal suspension */ +/* */ +/* INPUTS */ +/* */ +/* terminate_routine Termination/Timeout cleanup */ +/* routine */ +/* information Information pointer of the */ +/* cleanup routine */ +/* timeout Suspension timeout request */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_SUSPEND Indicates suspension is not */ +/* legal */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS IOCE_Suspend_Driver(VOID (*terminate_routine)(VOID *), + VOID *information, UNSIGNED timeout) +{ + +STATUS status; /* Completion status */ + + + /* Determine if there is a suspension error. */ + if (TCCE_Suspend_Error()) + + /* Suspension error, not called from a legal thread. */ + status = NU_INVALID_SUSPEND; + + else + + /* Call the actual suspend service. */ + status = IOC_Suspend_Driver(terminate_routine, information, timeout); + + /* Return the completion status. */ + return(status); +} + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/iod.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,89 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* iod.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* IO - Input/Output Driver Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains global data structures for use within the */ +/* Input/Output Driver Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* IOD_Created_Drivers_List Pointer to the linked-list */ +/* of created I/O drivers */ +/* IOD_Total_Drivers Total number of created */ +/* I/O drivers */ +/* IOD_List_Protect I/O driver list protection */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* io_defs.h I/O Driver Management consts */ +/* tc_defs.h Thread Control constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Updated copyright notice, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + +#include "io_defs.h" /* I/O Driver constants */ +#include "tc_defs.h" /* Thread control constants */ + + +/* IOD_Created_Drivers_List is the head pointer of the linked list of + created I/O drivers. If the list is NU_NULL, there are no I/O drivers + created. */ + +CS_NODE *IOD_Created_Drivers_List; + + +/* IOD_Total_Drivers contains the number of currently created + I/O drivers. */ + +UNSIGNED IOD_Total_Drivers; + + +/* IOD_List_Protect is a list protection structure used to block any other + thread from access to the created drivers list. */ + +TC_PROTECT IOD_List_Protect; + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/iof.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,240 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* iof.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* IO - Input/Output Driver Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains routines to obtain facts about the I/O Driver */ +/* Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* IOF_Established_Drivers Return total number of I/O */ +/* drivers */ +/* IOF_Driver_Pointers Return list of I/O driver */ +/* pointers */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* io_extr.h I/O driver functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Initial version of I/O driver */ +/* fact service file, version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "io_extr.h" /* I/O driver functions */ +#include "hi_extr.h" /* History functions */ + +/* Define external inner-component global data references. */ + +extern CS_NODE *IOD_Created_Drivers_List; +extern UNSIGNED IOD_Total_Drivers; +extern TC_PROTECT IOD_List_Protect; + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* IOF_Established_Drivers */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the current number of established I/O */ +/* drivers. I/O drivers previously deleted are no longer */ +/* considered established. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* IOD_Total_Drivers Number of established I/O */ +/* drivers */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED IOF_Established_Drivers(VOID) +{ + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Return the number of established I/O drivers. */ + return(IOD_Total_Drivers); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* IOF_Driver_Pointers */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function builds a list of driver pointers, starting at the */ +/* specified location. The number of driver pointers placed in */ +/* the list is equivalent to the total number of drivers or the */ +/* maximum number of pointers specified in the call. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect created list */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* pointer_list Pointer to the list area */ +/* maximum_pointers Maximum number of pointers */ +/* */ +/* OUTPUTS */ +/* */ +/* pointers Number of I/O driver pointers*/ +/* placed in the list */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected pointer retrieval */ +/* loop, resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Changed function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED IOF_Driver_Pointers(NU_DRIVER **pointer_list, + UNSIGNED maximum_pointers) +{ +CS_NODE *node_ptr; /* Pointer to each NU_DRIVER */ +UNSIGNED pointers; /* Number of pointers in list*/ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Initialize the number of pointers returned. */ + pointers = 0; + + /* Protect against access to the list of created I/O drivers. */ + TCT_Protect(&IOD_List_Protect); + + /* Loop until all driver pointers are in the list or until the maximum + list size is reached. */ + node_ptr = IOD_Created_Drivers_List; + while ((node_ptr) && (pointers < maximum_pointers)) + { + + /* Place the node into the destination list. */ + *pointer_list++ = (NU_DRIVER *) node_ptr; + + /* Increment the pointers variable. */ + pointers++; + + /* Position the node pointer to the next node. */ + node_ptr = node_ptr -> cs_next; + + /* Determine if the pointer is at the head of the list. */ + if (node_ptr == IOD_Created_Drivers_List) + + /* The list search is complete. */ + node_ptr = NU_NULL; + } + + /* Release protection against access to the list of created drivers. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the number of pointers in the list. */ + return(pointers); +} + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/ioi.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,135 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* ioi.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* IO - Input/Output Driver Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the initialization routine for the I/O Driver */ +/* Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* IOI_Initialize I/O Driver Initialize */ +/* */ +/* DEPENDENCIES */ +/* */ +/* io_defs.h I/O Driver component consts */ +/* tc_defs.h Thread control constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Updated copyright notice, */ +/* changed "void" to VOID, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "io_defs.h" /* I/O driver constants */ +#include "io_extr.h" /* I/O driver interfaces */ +#include "tc_defs.h" /* Thread control constants */ + + + +/* Define external inner-component global data references. */ + +extern CS_NODE *IOD_Created_Drivers_List; +extern UNSIGNED IOD_Total_Drivers; +extern TC_PROTECT IOD_List_Protect; + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* IOI_Initialize */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function initializes the data structures that control the */ +/* operation of the I/O driver component (IO). There are no I/O */ +/* drivers initially. This routine must be called from Supervisor */ +/* mode in Supervisor/User mode switched kernels. */ +/* */ +/* CALLED BY */ +/* */ +/* INC_Initialize System initialization */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* IOD_Created_Drivers_List List of created I/O drivers */ +/* IOD_Total_Drivers Number of created I/O drivers*/ +/* IOD_List_Protect Protection for driver list */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Updated copyright notice, */ +/* changed "void" to "VOID", */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +VOID IOI_Initialize(VOID) +{ + + /* Initialize the created I/O driver list to NU_NULL. */ + IOD_Created_Drivers_List = NU_NULL; + + /* Initialize the total number of created I/O drivers to 0. */ + IOD_Total_Drivers = 0; + + /* Initialize the list protection structure. */ + IOD_List_Protect.tc_tcb_pointer = NU_NULL; +} + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/lic.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,125 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* lic.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* LI - License Information */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the core routines for the License Information */ +/* component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* LIC_License_Information Return pointer to license */ +/* information string */ +/* */ +/* DEPENDENCIES */ +/* */ +/* nucleus.h System definitions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Replaced void with VOID, */ +/* added pointer for return value, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + +#include "nucleus.h" /* System definitions */ + + +/* Define external inner-component global data references. */ + +extern const CHAR LID_License_String[]; + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* LIC_Release_Information */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns a pointer to the license information */ +/* string. The information string identifies the customer and */ +/* product line Nucleus PLUS is licensed for. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* ptr Pointer to information string */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Replaced void with VOID, */ +/* added pointer for return value, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +CHAR *LIC_License_Information(VOID) +{ + +CHAR *ptr; + + /* Setup pointer to license string. */ + ptr = (CHAR *) &LID_License_String[0]; + + /* Return a pointer to the license information string. */ + return(ptr); +} + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/lid.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,70 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* lid.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* LI - License Information */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains customer license information in an ASCII */ +/* string format. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* LID_License_String License information string */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* nucleus.h System definitions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Updated copyright notice, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + +#include "nucleus.h" /* System definitions */ + +/* LID_License_String contains a string describing this license of Nucleus + PLUS. */ + +const CHAR LID_License_String[] = + "This code is in the public domain per the order of the Supreme Revolutionary Command"; + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/mb_defs.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,118 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* mb_defs.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* MB - Mailbox Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains data structure definitions and constants for */ +/* the message Mailbox component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* MB_MCB Mailbox control block */ +/* MB_SUSPEND Mailbox suspension block */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_defs.h Common service definitions */ +/* tc_defs.h Thread Control definitions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* removed protection structure */ +/* inside of each mailbox, added */ +/* padding logic, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "cs_defs.h" /* Common service constants */ +#include "tc_defs.h" /* Thread control constants */ + + +/* Check to see if the file has been included already. */ + +#ifndef MB_DEFS +#define MB_DEFS + + +/* Define constants local to this component. */ + +#define MB_MAILBOX_ID 0x4d424f58UL +#define MB_MESSAGE_SIZE 4 + + +/* Define the Mailbox Control Block data type. */ + +typedef struct MB_MCB_STRUCT +{ + CS_NODE mb_created; /* Node for linking to */ + /* created mailbox list */ + UNSIGNED mb_id; /* Internal MCB ID */ + CHAR mb_name[NU_MAX_NAME]; /* Mailbox name */ + BOOLEAN mb_message_present; /* Message present flag */ + BOOLEAN mb_fifo_suspend; /* Suspension type flag */ +#if PAD_2 + DATA_ELEMENT mb_padding[PAD_2]; +#endif + UNSIGNED mb_tasks_waiting; /* Number of waiting tasks*/ + UNSIGNED /* Message area */ + mb_message_area[MB_MESSAGE_SIZE]; + struct MB_SUSPEND_STRUCT + *mb_suspension_list; /* Suspension list */ +} MB_MCB; + + +/* Define the mailbox suspension structure. This structure is allocated off of + the caller's stack. */ + +typedef struct MB_SUSPEND_STRUCT +{ + CS_NODE mb_suspend_link; /* Link to suspend blocks */ + MB_MCB *mb_mailbox; /* Pointer to the mailbox */ + TC_TCB *mb_suspended_task; /* Task suspended */ + UNSIGNED *mb_message_area; /* Pointer to message area*/ + STATUS mb_return_status; /* Return status */ +} MB_SUSPEND; + +#endif + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/mb_extr.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,124 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* mb_extr.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* MB - Mailbox Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains function prototypes of all functions */ +/* accessible to other components. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* mb_defs.h Mailbox Management constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* changed the names of several */ +/* mailboxes services to reflect */ +/* the new file structure, */ +/* modified function interface to */ +/* exactly match the prototype, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "mb_defs.h" /* Include MB constants */ + + +/* Check to see if the file has been included already. */ + +#ifndef MB_EXTR +#define MB_EXTR + + +/* Initialization functions. */ + +VOID MBI_Initialize(VOID); + + +/* Core error checking functions. */ + +STATUS MBCE_Create_Mailbox(NU_MAILBOX *mailbox_ptr, CHAR *name, + OPTION suspend_type); +STATUS MBCE_Delete_Mailbox(NU_MAILBOX *mailbox_ptr); +STATUS MBCE_Send_To_Mailbox(NU_MAILBOX *mailbox_ptr, VOID *message, + UNSIGNED suspend); +STATUS MBCE_Receive_From_Mailbox(NU_MAILBOX *mailbox_ptr, + VOID *message, UNSIGNED suspend); + +/* Supplemental error checking functions. */ + +STATUS MBSE_Reset_Mailbox(NU_MAILBOX *mailbox_ptr); +STATUS MBSE_Broadcast_To_Mailbox(NU_MAILBOX *mailbox_ptr, + VOID *message, UNSIGNED suspend); + +/* Core processing functions. */ + +STATUS MBC_Create_Mailbox(NU_MAILBOX *mailbox_ptr, CHAR *name, + OPTION suspend_type); +STATUS MBC_Delete_Mailbox(NU_MAILBOX *mailbox_ptr); +STATUS MBC_Send_To_Mailbox(NU_MAILBOX *mailbox_ptr, VOID *message, + UNSIGNED suspend); +STATUS MBC_Receive_From_Mailbox(NU_MAILBOX *mailbox_ptr, + VOID *message, UNSIGNED suspend); + +/* Supplemental mailbox functions. */ + +STATUS MBS_Reset_Mailbox(NU_MAILBOX *mailbox_ptr); +STATUS MBS_Broadcast_To_Mailbox(NU_MAILBOX *mailbox_ptr, + VOID *message, UNSIGNED suspend); + +/* Mailbox fact retrieval functions. */ + +UNSIGNED MBF_Established_Mailboxes(VOID); +STATUS MBF_Mailbox_Information(NU_MAILBOX *mailbox_ptr, CHAR *name, + OPTION *suspend_type, DATA_ELEMENT *message_present, + UNSIGNED *tasks_waiting, NU_TASK **first_task); +UNSIGNED MBF_Mailbox_Pointers(NU_MAILBOX **pointer_list, + UNSIGNED maximum_pointers); + +#endif + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/mbc.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,992 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* mbc.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* MB - Mailbox Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the core routines for the Mailbox management */ +/* component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* MBC_Create_Mailbox Create a mailbox */ +/* MBC_Delete_Mailbox Delete a mailbox */ +/* MBC_Send_To_Mailbox Send a mailbox message */ +/* MBC_Receive_From_Mailbox Receive a mailbox message */ +/* MBC_Cleanup Cleanup on timeout or a */ +/* terminate condition */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* mb_extr.h Mailbox functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected pointer retrieval */ +/* loop, resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Moved non-core functions into */ +/* supplemental files, changed */ +/* function interfaces to match */ +/* those in prototype, added */ +/* register options, changed */ +/* protection logic to reduce */ +/* overhead, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "mb_extr.h" /* Mailbox functions */ +#include "hi_extr.h" /* History functions */ +#include "profiler.h" /* ProView interface */ + +/* Define external inner-component global data references. */ + +extern CS_NODE *MBD_Created_Mailboxes_List; +extern UNSIGNED MBD_Total_Mailboxes; +extern TC_PROTECT MBD_List_Protect; + + +/* Define internal component function prototypes. */ + +VOID MBC_Cleanup(VOID *information); + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* MBC_Create_Mailbox */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function creates a mailbox and then places it on the list */ +/* of created mailboxes. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* MBCE_Create_Mailbox Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Add node to linked-list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Data structure protect */ +/* TCT_Unprotect Un-protect data structure */ +/* */ +/* INPUTS */ +/* */ +/* mailbox_ptr Mailbox control block pointer*/ +/* name Mailbox name */ +/* suspend_type Suspension type */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interface to */ +/* match the prototype, added */ +/* register variable logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS MBC_Create_Mailbox(NU_MAILBOX *mailbox_ptr, CHAR *name, + OPTION suspend_type) +{ + +R1 MB_MCB *mailbox; /* Mailbox control block ptr */ +INT i; /* Working index variable */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input mailbox pointer into internal pointer. */ + mailbox = (MB_MCB *) mailbox_ptr; + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_CREATE_MAILBOX_ID, (UNSIGNED) mailbox, + (UNSIGNED) name, (UNSIGNED) suspend_type); + +#endif + + /* First, clear the mailbox ID just in case it is an old Mailbox + Control Block. */ + mailbox -> mb_id = 0; + + /* Fill in the mailbox name. */ + for (i = 0; i < NU_MAX_NAME; i++) + mailbox -> mb_name[i] = name[i]; + + /* Clear the message present flag- initial it to "no message present." */ + mailbox -> mb_message_present = NU_FALSE; + + /* Setup the mailbox suspension type. */ + if (suspend_type == NU_FIFO) + + /* FIFO suspension is selected, setup the flag accordingly. */ + mailbox -> mb_fifo_suspend = NU_TRUE; + else + + /* Priority suspension is selected. */ + mailbox -> mb_fifo_suspend = NU_FALSE; + + /* Clear the suspension list pointer. */ + mailbox -> mb_suspension_list = NU_NULL; + + /* Clear the number of tasks waiting on the mailbox counter. */ + mailbox -> mb_tasks_waiting = 0; + + /* Initialize link pointers. */ + mailbox -> mb_created.cs_previous = NU_NULL; + mailbox -> mb_created.cs_next = NU_NULL; + + /* Protect against access to the list of created mailboxes. */ + TCT_Protect(&MBD_List_Protect); + + /* At this point the mailbox is completely built. The ID can now be + set and it can be linked into the created mailbox list. */ + mailbox -> mb_id = MB_MAILBOX_ID; + + /* Link the mailbox into the list of created mailboxes and increment the + total number of mailboxes in the system. */ + CSC_Place_On_List(&MBD_Created_Mailboxes_List, &(mailbox -> mb_created)); + MBD_Total_Mailboxes++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMailBox(RT_PROF_CREATE_MAILBOX,mailbox,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + /* Release protection against access to the list of created mailboxes. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* MBC_Delete_Mailbox */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function deletes a mailbox and removes it from the list of */ +/* created mailboxes. All tasks suspended on the mailbox are */ +/* resumed. Note that this function does not free the memory */ +/* associated with the mailbox control block. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* MBCE_Delete_Mailbox Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove node from list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Protect Protect created list */ +/* TCT_Set_Current_Protect Setup current protection ptr */ +/* TCT_System_Protect Protect against system access*/ +/* TCT_System_Unprotect Release system protection */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* mailbox_ptr Mailbox control block pointer*/ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interface to */ +/* match the prototype, added */ +/* register variable logic, */ +/* optimized protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS MBC_Delete_Mailbox(NU_MAILBOX *mailbox_ptr) +{ + +R1 MB_MCB *mailbox; /* Mailbox control block ptr */ +MB_SUSPEND *suspend_ptr; /* Suspend block pointer */ +MB_SUSPEND *next_ptr; /* Next suspend block pointer*/ +STATUS preempt; /* Status for resume call */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input mailbox pointer into internal pointer. */ + mailbox = (MB_MCB *) mailbox_ptr; + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_DELETE_MAILBOX_ID, (UNSIGNED) mailbox, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Call protection just in case another thread is using the mailbox. */ + TCT_System_Protect(); + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMailBox(RT_PROF_DELETE_MAILBOX,mailbox,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + /* Clear the mailbox ID. */ + mailbox -> mb_id = 0; + + /* Clear protection. */ + TCT_Unprotect(); + + /* Protect against access to the list of created mailboxes. */ + TCT_Protect(&MBD_List_Protect); + + /* Remove the mailbox from the list of created mailboxes. */ + CSC_Remove_From_List(&MBD_Created_Mailboxes_List, + &(mailbox -> mb_created)); + + /* Decrement the total number of created mailboxes. */ + MBD_Total_Mailboxes--; + + /* Pickup the suspended task pointer list. */ + suspend_ptr = mailbox -> mb_suspension_list; + + /* Walk the chain task(s) currently suspended on the mailbox. */ + preempt = 0; + while (suspend_ptr) + { + + /* Protect against system access. */ + TCT_System_Protect(); + + /* Resume the suspended task. Insure that the status returned is + NU_MAILBOX_DELETED. */ + suspend_ptr -> mb_return_status = NU_MAILBOX_DELETED; + + /* Point to the next suspend structure in the link. */ + next_ptr = (MB_SUSPEND *) (suspend_ptr -> mb_suspend_link.cs_next); + + /* Resume the specified task. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> mb_suspended_task, + NU_MAILBOX_SUSPEND); + + /* Determine if the next is the same as the head pointer. */ + if (next_ptr == mailbox -> mb_suspension_list) + + /* Clear the suspension pointer to signal the end of the list + traversal. */ + suspend_ptr = NU_NULL; + else + + /* Position the suspend pointer to the next suspend block. */ + suspend_ptr = next_ptr; + + /* Setup current protection pointer. */ + TCT_Set_Current_Protect(&MBD_List_Protect); + + /* Unprotect the system protection. */ + TCT_System_Unprotect(); + } + + /* Determine if preemption needs to occur. */ + if (preempt) + + /* Transfer control to system to facilitate preemption. */ + TCT_Control_To_System(); + + /* Release protection against access to the list of created mailboxes. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return a successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* MBC_Send_To_Mailbox */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sends a 4-word message to the specified mailbox. */ +/* If there are one or more tasks suspended on the mailbox for a */ +/* message, the message is copied into the message area of the */ +/* first task waiting and that task is resumed. If the mailbox */ +/* is full, suspension of the calling task is possible. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* MBCE_Send_To_Mailbox Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Place on suspend list */ +/* CSC_Priority_Place_On_List Place on priority list */ +/* CSC_Remove_From_List Remove from suspend list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* TCC_Suspend_Task Suspend calling task */ +/* TCC_Task_Priority Pickup task's priority */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Current_Thread Pickup current thread pointer*/ +/* TCT_System_Protect Protect against system access*/ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* mailbox_ptr Mailbox control block pointer*/ +/* message Pointer to message to send */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If service is successful */ +/* NU_MAILBOX_FULL If mailbox is currently full */ +/* NU_TIMEOUT If timeout on service expires*/ +/* NU_MAILBOX_DELETED If mailbox is deleted during */ +/* suspension */ +/* NU_MAILBOX_RESET If mailbox is deleted during */ +/* suspension */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interface to */ +/* match the prototype, added */ +/* register variable logic, */ +/* optimized protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS MBC_Send_To_Mailbox(NU_MAILBOX *mailbox_ptr, VOID *message, + UNSIGNED suspend) +{ + +R1 MB_MCB *mailbox; /* Mailbox control block ptr */ +MB_SUSPEND suspend_block; /* Allocate suspension block */ +R2 MB_SUSPEND *suspend_ptr; /* Pointer to suspend block */ +R3 UNSIGNED *source_ptr; /* Pointer to source */ +R4 UNSIGNED *destination_ptr; /* Pointer to destination */ +TC_TCB *task; /* Task pointer */ +STATUS preempt; /* Preempt flag */ +STATUS status; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input mailbox pointer into internal pointer. */ + mailbox = (MB_MCB *) mailbox_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_SEND_TO_MAILBOX_ID, (UNSIGNED) mailbox, + (UNSIGNED) message, (UNSIGNED) suspend); + +#endif + + /* Initialize the status as successful. */ + status = NU_SUCCESS; + + /* Protect against simultaneous access to the mailbox. */ + TCT_System_Protect(); + + /* Determine if the mailbox is empty or full. */ + if (mailbox -> mb_message_present) + { + + /* Mailbox already has a message. Determine if suspension is + required. */ + if (suspend) + { + + /* Suspension is requested. */ + + /* Increment the number of tasks waiting. */ + mailbox -> mb_tasks_waiting++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMailBox(RT_PROF_SEND_TO_MAILBOX,mailbox,RT_PROF_WAIT); +#endif /* INCLUDE_PROVIEW */ + + /* Setup the suspend block and suspend the calling task. */ + suspend_ptr = &suspend_block; + suspend_ptr -> mb_mailbox = mailbox; + suspend_ptr -> mb_suspend_link.cs_next = NU_NULL; + suspend_ptr -> mb_suspend_link.cs_previous = NU_NULL; + suspend_ptr -> mb_message_area = (UNSIGNED *) message; + task = (TC_TCB *) TCT_Current_Thread(); + suspend_ptr -> mb_suspended_task = task; + + /* Determine if priority or FIFO suspension is associated with the + mailbox. */ + if (mailbox -> mb_fifo_suspend) + { + + /* FIFO suspension is required. Link the suspend block into + the list of suspended tasks on this mailbox. */ + CSC_Place_On_List((CS_NODE **) &(mailbox ->mb_suspension_list), + &(suspend_ptr -> mb_suspend_link)); + } + else + { + + /* Get the priority of the current thread so the suspend block + can be placed in the appropriate place. */ + suspend_ptr -> mb_suspend_link.cs_priority = + TCC_Task_Priority(task); + + CSC_Priority_Place_On_List((CS_NODE **) + &(mailbox -> mb_suspension_list), + &(suspend_ptr -> mb_suspend_link)); + } + + /* Finally, suspend the calling task. Note that the suspension call + automatically clears the protection on the mailbox. */ + TCC_Suspend_Task((NU_TASK *) task, NU_MAILBOX_SUSPEND, + MBC_Cleanup, suspend_ptr, suspend); + + /* Pickup the return status. */ + status = suspend_ptr -> mb_return_status; + } + else + { + + /* Return a status of NU_MAILBOX_FULL because there is no + room in the mailbox for the message. */ + status = NU_MAILBOX_FULL; +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMailBox(RT_PROF_SEND_TO_MAILBOX,mailbox,RT_PROF_FAIL); +#endif /* INCLUDE_PROVIEW */ + + } + } + else + { + + /* Determine if a task is waiting on the mailbox. */ + if (mailbox -> mb_suspension_list) + { + + /* Task is waiting on mailbox for a message. */ + + /* Decrement the number of tasks waiting on mailbox. */ + mailbox -> mb_tasks_waiting--; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMailBox(RT_PROF_SEND_TO_MAILBOX,mailbox,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + + /* Remove the first suspended block from the list. */ + suspend_ptr = mailbox -> mb_suspension_list; + CSC_Remove_From_List((CS_NODE **) + &(mailbox -> mb_suspension_list), + &(suspend_ptr -> mb_suspend_link)); + + /* Setup the source and destination pointers. */ + source_ptr = (UNSIGNED *) message; + destination_ptr = suspend_ptr -> mb_message_area; + + /* Copy the message directly into the waiting task's + destination. */ + *destination_ptr = *source_ptr; + *(destination_ptr + 1) = *(source_ptr + 1); + *(destination_ptr + 2) = *(source_ptr + 2); + *(destination_ptr + 3) = *(source_ptr + 3); + + /* Setup the appropriate return value. */ + suspend_ptr -> mb_return_status = NU_SUCCESS; + + /* Wakeup the waiting task and check for preemption. */ + preempt = + TCC_Resume_Task((NU_TASK *) suspend_ptr -> mb_suspended_task, + NU_MAILBOX_SUSPEND); + + /* Determine if preemption needs to take place. */ + if (preempt) + + /* Transfer control to the system if the resumed task function + detects a preemption condition. */ + TCT_Control_To_System(); + } + else + { + + /* Mailbox is empty and no task is waiting. */ + + /* Setup the source and destination pointers. */ + source_ptr = (UNSIGNED *) message; + destination_ptr = &(mailbox -> mb_message_area[0]); + + /* Place the message in the mailbox. */ + *destination_ptr = *source_ptr; + *(destination_ptr + 1) = *(source_ptr + 1); + *(destination_ptr + 2) = *(source_ptr + 2); + *(destination_ptr + 3) = *(source_ptr + 3); + + /* Indicate that the mailbox has a message. */ + mailbox -> mb_message_present = NU_TRUE; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMailBox(RT_PROF_SEND_TO_MAILBOX,mailbox,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + } + } + + /* Release protection. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* MBC_Receive_From_Mailbox */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function receives a message from the specified mailbox. */ +/* If there is a message currently in the mailbox, the message is */ +/* removed from the mailbox and placed in the caller's area. */ +/* Otherwise, if no message is present in the mailbox, suspension */ +/* of the calling task is possible. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* MBCE_Receive_From_Mailbox Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Place on suspend list */ +/* CSC_Priority_Place_On_List Place on priority list */ +/* CSC_Remove_From_List Remove from suspend list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* TCC_Suspend_Task Suspend calling task */ +/* TCC_Task_Priority Pickup task priority */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Current_Thread Pickup current thread pointer*/ +/* TCT_System_Protect Protect mailbox */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* mailbox_ptr Mailbox control block pointer*/ +/* message Pointer to message to send */ +/* suspend Suspension option if empty */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If service is successful */ +/* NU_MAILBOX_EMPTY If mailbox is currently empty*/ +/* NU_TIMEOUT If timeout on service expires*/ +/* NU_MAILBOX_DELETED If mailbox is deleted during */ +/* suspension */ +/* NU_MAILBOX_RESET If mailbox is deleted during */ +/* suspension */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interface to */ +/* match the prototype, added */ +/* register variable logic, */ +/* optimized protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS MBC_Receive_From_Mailbox(NU_MAILBOX *mailbox_ptr, VOID *message, + UNSIGNED suspend) +{ + +R1 MB_MCB *mailbox; /* Mailbox control block ptr */ +MB_SUSPEND suspend_block; /* Allocate suspension block */ +R2 MB_SUSPEND *suspend_ptr; /* Pointer to suspend block */ +R3 UNSIGNED *source_ptr; /* Pointer to source */ +R4 UNSIGNED *destination_ptr; /* Pointer to destination */ +TC_TCB *task; /* Task pointer */ +STATUS preempt; /* Preemption flag */ +STATUS status; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input mailbox pointer into internal pointer. */ + mailbox = (MB_MCB *) mailbox_ptr; + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_RECEIVE_FROM_MAILBOX_ID, (UNSIGNED) mailbox, + (UNSIGNED) message, (UNSIGNED) suspend); + +#endif + + /* Initialize the status as successful. */ + status = NU_SUCCESS; + + /* Protect against simultaneous access to the mailbox. */ + TCT_System_Protect(); + + /* Determine if the mailbox is empty or full. */ + if (mailbox -> mb_message_present) + { + + /* Copy message from mailbox into the caller's area. */ + + /* Setup the source and destination pointers. */ + source_ptr = &(mailbox -> mb_message_area[0]); + destination_ptr = (UNSIGNED *) message; + + /* Copy the message directly into the waiting task's + destination. */ + *destination_ptr = *source_ptr; + *(destination_ptr + 1) = *(source_ptr + 1); + *(destination_ptr + 2) = *(source_ptr + 2); + *(destination_ptr + 3) = *(source_ptr + 3); + + /* Determine if another task is waiting to place something into the + mailbox. */ + if (mailbox -> mb_suspension_list) + { + + /* Yes, another task is waiting to send something to the + mailbox. */ + + /* Decrement the number of tasks waiting counter. */ + mailbox -> mb_tasks_waiting--; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMailBox(RT_PROF_RECEIVE_FROM_MAILBOX,mailbox,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + /* Remove the first suspended block from the list. */ + suspend_ptr = mailbox -> mb_suspension_list; + CSC_Remove_From_List((CS_NODE **) + &(mailbox -> mb_suspension_list), + &(suspend_ptr -> mb_suspend_link)); + + /* Setup the source and destination pointers. */ + source_ptr = suspend_ptr -> mb_message_area; + destination_ptr = &(mailbox -> mb_message_area[0]); + + /* Copy the message directly into the waiting task's + destination. */ + *destination_ptr = *source_ptr; + *(destination_ptr + 1) = *(source_ptr + 1); + *(destination_ptr + 2) = *(source_ptr + 2); + *(destination_ptr + 3) = *(source_ptr + 3); + + /* Setup the appropriate return value. */ + suspend_ptr -> mb_return_status = NU_SUCCESS; + + /* Resume the suspended task. */ + preempt = + TCC_Resume_Task((NU_TASK *) suspend_ptr -> mb_suspended_task, + NU_MAILBOX_SUSPEND); + + /* Determine if a preempt condition is present. */ + if (preempt) + + /* Transfer control to the system if the resumed task function + detects a preemption condition. */ + TCT_Control_To_System(); + } + else + { + + /* Clear the message present flag. */ + mailbox -> mb_message_present = NU_FALSE; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMailBox(RT_PROF_RECEIVE_FROM_MAILBOX,mailbox,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + + } + + } + else + { + + /* Mailbox is empty. Determine if suspension is required. */ + if (suspend) + { + + /* Suspension is required. */ + + /* Increment the number of tasks waiting on the mailbox counter. */ + mailbox -> mb_tasks_waiting++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMailBox(RT_PROF_RECEIVE_FROM_MAILBOX,mailbox,RT_PROF_WAIT); +#endif /* INCLUDE_PROVIEW */ + + /* Setup the suspend block and suspend the calling task. */ + suspend_ptr = &suspend_block; + suspend_ptr -> mb_mailbox = mailbox; + suspend_ptr -> mb_suspend_link.cs_next = NU_NULL; + suspend_ptr -> mb_suspend_link.cs_previous = NU_NULL; + suspend_ptr -> mb_message_area = (UNSIGNED *) message; + task = (TC_TCB *) TCT_Current_Thread(); + suspend_ptr -> mb_suspended_task = task; + + /* Determine if priority or FIFO suspension is associated with the + mailbox. */ + if (mailbox -> mb_fifo_suspend) + { + + /* FIFO suspension is required. Link the suspend block into + the list of suspended tasks on this mailbox. */ + CSC_Place_On_List((CS_NODE **) &(mailbox ->mb_suspension_list), + &(suspend_ptr -> mb_suspend_link)); + } + else + { + + /* Get the priority of the current thread so the suspend block + can be placed in the appropriate place. */ + suspend_ptr -> mb_suspend_link.cs_priority = + TCC_Task_Priority(task); + + CSC_Priority_Place_On_List((CS_NODE **) + &(mailbox -> mb_suspension_list), + &(suspend_block.mb_suspend_link)); + } + + /* Finally, suspend the calling task. Note that the suspension call + automatically clears the protection on the mailbox. */ + TCC_Suspend_Task((NU_TASK *) task, NU_MAILBOX_SUSPEND, + MBC_Cleanup, &suspend_block, suspend); + + /* Pickup the return status. */ + status = suspend_ptr -> mb_return_status; + } + else + { + + /* Return a status of NU_MAILBOX_EMPTY because there is + nothing in the mailbox. */ + status = NU_MAILBOX_EMPTY; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMailBox(RT_PROF_RECEIVE_FROM_MAILBOX,mailbox,RT_PROF_FAIL); +#endif /* INCLUDE_PROVIEW */ + } + + } + + /* Release protection. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* MBC_Cleanup */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for removing a suspension block */ +/* from a mailbox. It is not called unless a timeout or a task */ +/* terminate is in progress. Note that protection is already in */ +/* effect - the same protection at suspension time. */ +/* */ +/* CALLED BY */ +/* */ +/* TCC_Timeout Task timeout */ +/* TCC_Terminate Task terminate */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove suspend block from */ +/* the suspension list */ +/* */ +/* INPUTS */ +/* */ +/* information Pointer to suspend block */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +VOID MBC_Cleanup(VOID *information) +{ + +MB_SUSPEND *suspend_ptr; /* Suspension block pointer */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Use the information pointer as a suspend pointer. */ + suspend_ptr = (MB_SUSPEND *) information; + + /* By default, indicate that the service timed-out. It really does not + matter if this function is called from a terminate request since + the task does not resume. */ + suspend_ptr -> mb_return_status = NU_TIMEOUT; + + /* Decrement the number of tasks waiting counter. */ + (suspend_ptr -> mb_mailbox) -> mb_tasks_waiting--; + + /* Unlink the suspend block from the suspension list. */ + CSC_Remove_From_List((CS_NODE **) + &((suspend_ptr -> mb_mailbox) -> mb_suspension_list), + &(suspend_ptr -> mb_suspend_link)); + + /* Return to user mode */ + NU_USER_MODE(); +} + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/mbce.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,390 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* mbce.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* MB - Mailbox Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the error checking routines for the core */ +/* functions in the Mailbox component. This permits easy removal */ +/* of error checking logic when it is not needed. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* MBCE_Create_Mailbox Create a mailbox */ +/* MBCE_Delete_Mailbox Delete a mailbox */ +/* MBCE_Send_To_Mailbox Send a mailbox message */ +/* MBCE_Receive_From_Mailbox Receive a mailbox message */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* mb_extr.h Mailbox functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Created new file that contains */ +/* error checking shells for core */ +/* mailbox functions, also */ +/* changed interface to exactly */ +/* match prototype, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "mb_extr.h" /* Mailbox functions */ + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* MBCE_Create_Mailbox */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the mailbox create function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* MBC_Create_Mailbox Actual create mailbox funct. */ +/* */ +/* INPUTS */ +/* */ +/* mailbox_ptr Mailbox control block pointer*/ +/* name Mailbox name */ +/* suspend_type Suspension type */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_MAILBOX Mailbox pointer is NULL */ +/* NU_INVALID_SUSPEND Suspension type is invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified interface to exactly */ +/* match prototype, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS MBCE_Create_Mailbox(NU_MAILBOX *mailbox_ptr, CHAR *name, + OPTION suspend_type) +{ + +MB_MCB *mailbox; /* Mailbox control block ptr */ +STATUS status; /* Completion status */ + + + /* Move input mailbox pointer into internal pointer. */ + mailbox = (MB_MCB *) mailbox_ptr; + + /* Check for a NULL mailbox pointer or an already created mailbox. */ + if ((mailbox == NU_NULL) || (mailbox -> mb_id == MB_MAILBOX_ID)) + + /* Invalid mailbox control block pointer. */ + status = NU_INVALID_MAILBOX; + + else if ((suspend_type != NU_FIFO) && (suspend_type != NU_PRIORITY)) + + /* Invalid suspension type. */ + status = NU_INVALID_SUSPEND; + + else + + /* Call the actual service to create the mailbox. */ + status = MBC_Create_Mailbox(mailbox_ptr, name, suspend_type); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* MBCE_Delete_Mailbox */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the actual delete mailbox function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* MBC_Delete_Mailbox Actual delete mailbox funct. */ +/* */ +/* INPUTS */ +/* */ +/* mailbox_ptr Mailbox control block pointer*/ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_MAILBOX Invalid mailbox supplied */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified interface to exactly */ +/* match prototype, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS MBCE_Delete_Mailbox(NU_MAILBOX *mailbox_ptr) +{ + +MB_MCB *mailbox; /* Mailbox control block ptr */ +STATUS status; /* Completion status */ + + + /* Move input mailbox pointer into internal pointer. */ + mailbox = (MB_MCB *) mailbox_ptr; + + /* Determine if the mailbox pointer is valid. */ + if ((mailbox) && (mailbox -> mb_id == MB_MAILBOX_ID)) + + /* Mailbox pointer is valid, call function to delete it. */ + status = MBC_Delete_Mailbox(mailbox_ptr); + + else + + /* Mailbox pointer is invalid, indicate in completion status. */ + status = NU_INVALID_MAILBOX; + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* MBCE_Send_To_Mailbox */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the send-to-mailbox function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* MBC_Sent_To_Mailbox Actual mailbox send function */ +/* TCCE_Suspend_Error Check suspend validity */ +/* */ +/* INPUTS */ +/* */ +/* mailbox_ptr Mailbox control block pointer*/ +/* message Pointer to message to send */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_MAILBOX Mailbox pointer is invalid */ +/* NU_INVALID_POINTER Message pointer is invalid */ +/* NU_INVALID_SUSPEND Invalid suspend request */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified interface to exactly */ +/* match prototype, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS MBCE_Send_To_Mailbox(NU_MAILBOX *mailbox_ptr, VOID *message, + UNSIGNED suspend) +{ + +MB_MCB *mailbox; /* Mailbox control block ptr */ +STATUS status; /* Completion status */ + + + /* Move input mailbox pointer into internal pointer. */ + mailbox = (MB_MCB *) mailbox_ptr; + + /* Determine if mailbox pointer is invalid. */ + if (mailbox == NU_NULL) + + /* Mailbox pointer is invalid, indicate in completion status. */ + status = NU_INVALID_MAILBOX; + + else if (mailbox -> mb_id != MB_MAILBOX_ID) + + /* Mailbox pointer is invalid, indicate in completion status. */ + status = NU_INVALID_MAILBOX; + + else if (message == NU_NULL) + + /* Message pointer is invalid, indicate in completion status. */ + status = NU_INVALID_POINTER; + + else if ((suspend) && (TCCE_Suspend_Error())) + + /* Indicate that suspension is only valid from a task thread. */ + status = NU_INVALID_SUSPEND; + + else + + /* Parameters are valid, call actual function. */ + status = MBC_Send_To_Mailbox(mailbox_ptr, message, suspend); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* MBCE_Receive_From_Mailbox */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the receive message from mailbox function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* MBC_Receive_From_Mailbox Actual receive function */ +/* TCCE_Suspend_Error Check suspend validity */ +/* */ +/* INPUTS */ +/* */ +/* mailbox_ptr Mailbox control block pointer*/ +/* message Pointer to message to send */ +/* suspend Suspension option if empty */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_MAILBOX Mailbox pointer is invalid */ +/* NU_INVALID_POINTER Message pointer is invalid */ +/* NU_INVALID_SUSPEND Invalid suspend request */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified interface to exactly */ +/* match prototype, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS MBCE_Receive_From_Mailbox(NU_MAILBOX *mailbox_ptr, VOID *message, + UNSIGNED suspend) +{ + +MB_MCB *mailbox; /* Mailbox control block ptr */ +STATUS status; /* Completion status */ + + + /* Move input mailbox pointer into internal pointer. */ + mailbox = (MB_MCB *) mailbox_ptr; + + /* Determine if mailbox pointer is invalid. */ + if (mailbox == NU_NULL) + + /* Mailbox pointer is invalid, indicate in completion status. */ + status = NU_INVALID_MAILBOX; + + else if (mailbox -> mb_id != MB_MAILBOX_ID) + + /* Mailbox pointer is invalid, indicate in completion status. */ + status = NU_INVALID_MAILBOX; + + else if (message == NU_NULL) + + /* Message pointer is invalid, indicate in completion status. */ + status = NU_INVALID_POINTER; + + else if ((suspend) && (TCCE_Suspend_Error())) + + /* Indicate that suspension is only valid from a task thread. */ + status = NU_INVALID_SUSPEND; + + else + + /* Parameters are valid, call actual function. */ + status = MBC_Receive_From_Mailbox(mailbox_ptr, message, suspend); + + /* Return the completion status. */ + return(status); +} + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/mbd.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,88 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* mbd.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* MB - Mailbox Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains global data structures for use within the */ +/* mailbox management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* MBD_Created_Mailboxes_List Pointer to the linked-list */ +/* of created mailboxes */ +/* MBD_Total_Mailboxes Total number of created */ +/* mailboxes */ +/* MBD_List_Protect Mailbox list protection */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* mb_defs.h Mailbox Management constants */ +/* tc_defs.h Thread Control constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified file header, resulting */ +/* in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + +#include "mb_defs.h" /* Mailbox constants */ + + +/* MBD_Created_Mailboxes_List is the head pointer of the linked list of + created mailboxes. If the list is NU_NULL, there are no mailboxes + created. */ + +CS_NODE *MBD_Created_Mailboxes_List; + + +/* MBD_Total_Mailboxes contains the number of currently created + mailboxes. */ + +UNSIGNED MBD_Total_Mailboxes; + + +/* MBD_List_Protect is a list protection structure used to block any other + thread from access to the created mailbox list. */ + +TC_PROTECT MBD_List_Protect; + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/mbf.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,374 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* mbf.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* MB - Mailbox Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains routines to obtain facts about the Mailbox */ +/* management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* MBF_Established_Mailboxes Number of created mailboxes */ +/* MBF_Mailbox_Pointers Build mailbox pointer list */ +/* MBF_Mailbox_Information Retrieve mailbox information */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* mb_extr.h Mailbox functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Initial version of mailbox fact */ +/* service file, version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 11-18-1996 Protected Informational service */ +/* from NULL Control Block pointers */ +/* creating 1.2a. (SPR220) */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "mb_extr.h" /* Mailbox functions */ +#include "hi_extr.h" /* History functions */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *MBD_Created_Mailboxes_List; +extern UNSIGNED MBD_Total_Mailboxes; +extern TC_PROTECT MBD_List_Protect; + + +/* Define internal component function prototypes. */ + +VOID MBC_Cleanup(VOID *information); + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* MBF_Established_Mailboxes */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the current number of established */ +/* mailboxes. Mailboxes previously deleted are no longer */ +/* considered established. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* MBD_Total_Mailboxes Number of established */ +/* mailboxes */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +UNSIGNED MBF_Established_Mailboxes(VOID) +{ + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Return the number of established mailboxes. */ + return(MBD_Total_Mailboxes); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* MBF_Mailbox_Pointers */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function builds a list of mailbox pointers, starting at the */ +/* specified location. The number of mailbox pointers placed in */ +/* the list is equivalent to the total number of mailboxes or the */ +/* maximum number of pointers specified in the call. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect created list */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* pointer_list Pointer to the list area */ +/* maximum_pointers Maximum number of pointers */ +/* */ +/* OUTPUTS */ +/* */ +/* pointers Number of mailboxes placed */ +/* in the list */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected pointer retrieval */ +/* loop, resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Changed function interface to */ +/* match the prototype, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED MBF_Mailbox_Pointers(NU_MAILBOX **pointer_list, + UNSIGNED maximum_pointers) +{ +CS_NODE *node_ptr; /* Pointer to each MCB */ +UNSIGNED pointers; /* Number of pointers in list*/ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Initialize the number of pointers returned. */ + pointers = 0; + + /* Protect against access to the list of created mailboxes. */ + TCT_Protect(&MBD_List_Protect); + + /* Loop until all mailbox pointers are in the list or until the maximum + list size is reached. */ + node_ptr = MBD_Created_Mailboxes_List; + while ((node_ptr) && (pointers < maximum_pointers)) + { + + /* Place the node into the destination list. */ + *pointer_list++ = (NU_MAILBOX *) node_ptr; + + /* Increment the pointers variable. */ + pointers++; + + /* Position the node pointer to the next node. */ + node_ptr = node_ptr -> cs_next; + + /* Determine if the pointer is at the head of the list. */ + if (node_ptr == MBD_Created_Mailboxes_List) + + /* The list search is complete. */ + node_ptr = NU_NULL; + } + + /* Release protection against access to the list of created mailboxes. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the number of pointers in the list. */ + return(pointers); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* MBF_Mailbox_Information */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns information about the specified mailbox. */ +/* However, if the supplied mailbox pointer is invalid, the */ +/* function simply returns an error status. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_System_Protect Protect mailbox */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* mailbox_ptr Pointer to the mailbox */ +/* name Destination for the name */ +/* suspend_type Destination for the type of */ +/* suspension */ +/* message_present Destination for the message */ +/* present flag */ +/* tasks_waiting Destination for the tasks */ +/* waiting count */ +/* first_task Destination for the pointer */ +/* to the first task waiting */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If a valid mailbox pointer */ +/* is supplied */ +/* NU_INVALID_MAILBOX If mailbox pointer invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interface to */ +/* match the prototype, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 11-18-1996 Corrected SPR220. */ +/* */ +/*************************************************************************/ +STATUS MBF_Mailbox_Information(NU_MAILBOX *mailbox_ptr, CHAR *name, + OPTION *suspend_type, DATA_ELEMENT *message_present, + UNSIGNED *tasks_waiting, NU_TASK **first_task) +{ + +MB_MCB *mailbox; /* Mailbox control block ptr */ +int i; /* Working integer variable */ +STATUS completion; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input mailbox pointer into internal pointer. */ + mailbox = (MB_MCB *) mailbox_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Determine if this mailbox id is valid. */ + if ((mailbox != NU_NULL) && (mailbox -> mb_id == MB_MAILBOX_ID)) + { + + /* Setup protection of the mailbox. */ + TCT_System_Protect(); + + /* The mailbox pointer is valid. Reflect this in the completion + status and fill in the actual information. */ + completion = NU_SUCCESS; + + /* Copy the mailbox's name. */ + for (i = 0; i < NU_MAX_NAME; i++) + *name++ = mailbox -> mb_name[i]; + + /* Determine the suspension type. */ + if (mailbox -> mb_fifo_suspend) + *suspend_type = NU_FIFO; + else + *suspend_type = NU_PRIORITY; + + /* Indicate whether or not there is a message in the mailbox. */ + *message_present = mailbox -> mb_message_present; + + /* Retrieve the number of tasks waiting and the pointer to the + first task waiting. */ + *tasks_waiting = mailbox -> mb_tasks_waiting; + if (mailbox -> mb_suspension_list) + + /* There is a task waiting. */ + *first_task = (NU_TASK *) + (mailbox -> mb_suspension_list) -> mb_suspended_task; + else + + /* There are no tasks waiting. */ + *first_task = NU_NULL; + + /* Release protection. */ + TCT_Unprotect(); + } + else + + /* Indicate that the mailbox pointer is invalid. */ + completion = NU_INVALID_MAILBOX; + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the appropriate completion status. */ + return(completion); +} + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/mbi.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,125 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* mbi.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* MB - Mailbox Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the initialization routine for the mailbox */ +/* management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* MBI_Initialize Mailbox Management Initialize*/ +/* */ +/* DEPENDENCIES */ +/* */ +/* mb_defs.h Mailbox component constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Update file copyright informaion, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "mb_defs.h" /* Mailbox constants */ +#include "mb_extr.h" /* Mailbox interfaces */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *MBD_Created_Mailboxes_List; +extern UNSIGNED MBD_Total_Mailboxes; +extern TC_PROTECT MBD_List_Protect; + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* MBI_Initialize */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function initializes the data structures that control the */ +/* operation of the Mailbox component (MB). There are no mailboxes */ +/* initially. This routine must be called from Supervisor mode in */ +/* Supervisor/User mode switched kernels. */ +/* */ +/* CALLED BY */ +/* */ +/* INC_Initialize System initialization */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* MBD_Created_Mailboxes_List List of created mailboxes */ +/* MBD_Total_Mailboxes Number of created mailboxes */ +/* MBD_List_Protect Protection for mailbox list */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +VOID MBI_Initialize(VOID) +{ + /* Initialize the created mailbox list to NU_NULL. */ + MBD_Created_Mailboxes_List = NU_NULL; + + /* Initialize the total number of created mailboxes to 0. */ + MBD_Total_Mailboxes = 0; + + /* Initialize the list protection structure. */ + MBD_List_Protect.tc_tcb_pointer = NU_NULL; +} + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/mbs.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,496 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* mbs.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* MB - Mailbox Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the core routines for the Mailbox management */ +/* component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* MBS_Reset_Mailbox Reset a mailbox */ +/* MBS_Broadcast_To_Mailbox Broadcast a mailbox message */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* mb_extr.h Mailbox functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Initial version of supplemental */ +/* mailbox service file, */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-23-2001 Fixed problem with resuming task in */ +/* MBS_Broadcast_To_Mailbox */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "mb_extr.h" /* Mailbox functions */ +#include "hi_extr.h" /* History functions */ +#include "profiler.h" /* ProView interface */ + + +/* Define internal component function prototypes. */ + +VOID MBC_Cleanup(VOID *information); + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* MBS_Reset_Mailbox */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function resets a mailbox back to the initial state. Any */ +/* message in the mailbox is discarded. Also, all tasks suspended */ +/* on the mailbox are resumed with the reset completion status. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* MBSE_Reset_Mailbox Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_System_Protect Protect mailbox */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* mailbox_ptr Mailbox control block pointer*/ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* NAME DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interface to */ +/* match the prototype, added */ +/* register variable logic, */ +/* optimized protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS MBS_Reset_Mailbox(NU_MAILBOX *mailbox_ptr) +{ + +R1 MB_MCB *mailbox; /* Mailbox control block ptr */ +R2 MB_SUSPEND *suspend_ptr; /* Suspend block pointer */ +MB_SUSPEND *next_ptr; /* Next suspend block pointer*/ +STATUS preempt; /* Status for resume call */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input mailbox pointer into internal pointer. */ + mailbox = (MB_MCB *) mailbox_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_RESET_MAILBOX_ID, (UNSIGNED) mailbox, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Protect against access to the mailbox. */ + TCT_System_Protect(); + + /* Pickup the suspended task pointer list. */ + suspend_ptr = mailbox -> mb_suspension_list; + + /* Walk the chain task(s) currently suspended on the mailbox. */ + preempt = 0; + while (suspend_ptr) + { + + /* Resume the suspended task. Insure that the status returned is + NU_MAILBOX_RESET. */ + suspend_ptr -> mb_return_status = NU_MAILBOX_RESET; + + /* Point to the next suspend structure in the link. */ + next_ptr = (MB_SUSPEND *) (suspend_ptr -> mb_suspend_link.cs_next); + + /* Resume the specified task. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> mb_suspended_task, + NU_MAILBOX_SUSPEND); + + /* Determine if the next is the same as the head pointer. */ + if (next_ptr == mailbox -> mb_suspension_list) + + /* Clear the suspension pointer to signal the end of the list + traversal. */ + suspend_ptr = NU_NULL; + else + + /* Position the suspend pointer to the next suspend block. */ + suspend_ptr = next_ptr; + } + + /* Initialize the mailbox. */ + mailbox -> mb_message_present = NU_FALSE; + mailbox -> mb_tasks_waiting = 0; + mailbox -> mb_suspension_list = NU_NULL; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMailBox(RT_PROF_RESET_MAILBOX,mailbox,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + + /* Determine if preemption needs to occur. */ + if (preempt) + + /* Transfer control to system to facilitate preemption. */ + TCT_Control_To_System(); + + /* Release protection. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return a successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* MBS_Broadcast_To_Mailbox */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sends a message to all tasks currently waiting for */ +/* a message from the mailbox. If no tasks are waiting, this */ +/* service behaves like a normal send message. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* MBSE_Broadcast_To_Mailbox Broadcast to a mailbox */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Place on suspend list */ +/* CSC_Priority_Place_On_List Place on priority list */ +/* CSC_Remove_From_List Remove from suspend list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* TCC_Suspend_Task Suspend calling task */ +/* TCC_Task_Priority Priority of specified task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Current_Thread Pickup current thread pointer*/ +/* TCT_System_Protect Protect mailbox */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* mailbox_ptr Mailbox control block pointer*/ +/* message Pointer to message to send */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If service is successful */ +/* NU_MAILBOX_FULL If mailbox is currently full */ +/* NU_TIMEOUT If timeout on service expires*/ +/* NU_MAILBOX_DELETED If mailbox is deleted during */ +/* suspension */ +/* NU_MAILBOX_RESET If mailbox is deleted during */ +/* suspension */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interface to */ +/* match the prototype, added */ +/* register variable logic, */ +/* optimized protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS MBS_Broadcast_To_Mailbox(NU_MAILBOX *mailbox_ptr, VOID *message, + UNSIGNED suspend) +{ + +R1 MB_MCB *mailbox; /* Mailbox control block ptr */ +MB_SUSPEND suspend_block; /* Allocate suspension block */ +R2 MB_SUSPEND *suspend_ptr; /* Pointer to suspend block */ +MB_SUSPEND *suspend_head; /* Pointer to suspend head */ +MB_SUSPEND *next_suspend_ptr; /* Get before restarting task*/ +STATUS preempt; /* Preemption flag */ +R3 UNSIGNED *source_ptr; /* Pointer to source */ +R4 UNSIGNED *destination_ptr; /* Pointer to destination */ +TC_TCB *task; /* Task pointer */ +STATUS status; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input mailbox pointer into internal pointer. */ + mailbox = (MB_MCB *) mailbox_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_BROADCAST_TO_MAILBOX_ID, (UNSIGNED) mailbox, + (UNSIGNED) message, (UNSIGNED) suspend); + +#endif + + /* Initialize the status as successful. */ + status = NU_SUCCESS; + + /* Protect against simultaneous access to the mailbox. */ + TCT_System_Protect(); + + /* Determine if the mailbox is empty or full. */ + if (mailbox -> mb_message_present) + { + + /* Mailbox already has a message. Determine if suspension is + required. */ + if (suspend) + { + + /* Suspension is requested. */ + + /* Increment the number of tasks suspended on the mailbox. */ + mailbox -> mb_tasks_waiting++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMailBox(RT_PROF_BROADCAST_TO_MAILBOX,mailbox,RT_PROF_WAIT); +#endif /* INCLUDE_PROVIEW */ + + /* Setup the suspend block and suspend the calling task. */ + suspend_ptr = &suspend_block; + suspend_ptr -> mb_mailbox = mailbox; + suspend_ptr -> mb_suspend_link.cs_next = NU_NULL; + suspend_ptr -> mb_suspend_link.cs_previous = NU_NULL; + suspend_ptr -> mb_message_area = (UNSIGNED *) message; + task = (TC_TCB *) TCT_Current_Thread(); + suspend_ptr -> mb_suspended_task = task; + + /* Determine if priority or FIFO suspension is associated with the + mailbox. */ + if (mailbox -> mb_fifo_suspend) + { + + /* FIFO suspension is required. Link the suspend block into + the list of suspended tasks on this mailbox. */ + CSC_Place_On_List((CS_NODE **) &(mailbox ->mb_suspension_list), + &(suspend_ptr -> mb_suspend_link)); + } + else + { + + /* Get the priority of the current thread so the suspend block + can be placed in the appropriate place. */ + suspend_ptr -> mb_suspend_link.cs_priority = + TCC_Task_Priority(task); + + CSC_Priority_Place_On_List((CS_NODE **) + &(mailbox -> mb_suspension_list), + &(suspend_ptr -> mb_suspend_link)); + } + + /* Finally, suspend the calling task. Note that the suspension call + automatically clears the protection on the mailbox. */ + TCC_Suspend_Task((NU_TASK *) task, NU_MAILBOX_SUSPEND, + MBC_Cleanup, suspend_ptr, suspend); + + /* Pickup the return status. */ + status = suspend_ptr -> mb_return_status; + } + else + { + + /* Return a status of NU_MAILBOX_FULL because there is no + room in the mailbox for the message. */ + status = NU_MAILBOX_FULL; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMailBox(RT_PROF_BROADCAST_TO_MAILBOX,mailbox,RT_PROF_FAIL); +#endif /* INCLUDE_PROVIEW */ + + } + } + else + { + + /* Determine if a task is waiting on the mailbox. */ + if (mailbox -> mb_suspension_list) + { + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMailBox(RT_PROF_BROADCAST_TO_MAILBOX,mailbox,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + + /* At least one task is waiting on mailbox for a message. */ + + /* Save off the suspension list and and then clear out the + mailbox suspension. */ + suspend_head = mailbox -> mb_suspension_list; + mailbox -> mb_suspension_list = NU_NULL; + + /* Loop to wakeup all of the tasks waiting on the mailbox for + a message. */ + suspend_ptr = suspend_head; + preempt = 0; + do + { + + /* Setup the source and destination pointers. */ + source_ptr = (UNSIGNED *) message; + destination_ptr = suspend_ptr -> mb_message_area; + + /* Copy the message directly into the waiting task's + destination. */ + *destination_ptr = *source_ptr; + *(destination_ptr + 1) = *(source_ptr + 1); + *(destination_ptr + 2) = *(source_ptr + 2); + *(destination_ptr + 3) = *(source_ptr + 3); + + /* Setup the appropriate return value. */ + suspend_ptr -> mb_return_status = NU_SUCCESS; + + /* Move the suspend pointer along to the next block. */ + next_suspend_ptr = (MB_SUSPEND *) + suspend_ptr -> mb_suspend_link.cs_next; + + /* Wakeup each task waiting. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> mb_suspended_task, + NU_MAILBOX_SUSPEND); + suspend_ptr = next_suspend_ptr; + + } while (suspend_ptr != suspend_head); + + /* Clear the number of tasks waiting counter of the mailbox. */ + mailbox -> mb_tasks_waiting = 0; + + /* Determine if a preempt condition is present. */ + if (preempt) + + /* Transfer control to the system if the resumed task function + detects a preemption condition. */ + TCT_Control_To_System(); + } + else + { + + /* Mailbox is empty and no task is waiting. */ + + /* Setup the source and destination pointers. */ + source_ptr = (UNSIGNED *) message; + destination_ptr = &(mailbox -> mb_message_area[0]); + + /* Place the message in the mailbox. */ + *destination_ptr = *source_ptr; + *(destination_ptr + 1) = *(source_ptr + 1); + *(destination_ptr + 2) = *(source_ptr + 2); + *(destination_ptr + 3) = *(source_ptr + 3); + + /* Indicate that the mailbox has a message. */ + mailbox -> mb_message_present = NU_TRUE; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpMailBox(RT_PROF_BROADCAST_TO_MAILBOX,mailbox,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + } + } + + /* Release protection. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(status); +} + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/mbse.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,222 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* mbse.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* MB - Mailbox Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the error checking routines for the functions */ +/* in the Mailbox component. This permits easy removal of error */ +/* checking logic when it is not needed. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* MBSE_Reset_Mailbox Reset a mailbox */ +/* MBSE_Receive_From_Mailbox Receive a mailbox message */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* mb_extr.h Mailbox functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Created initial version 1.1 from */ +/* routines originally in core */ +/* error checking file */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "mb_extr.h" /* Mailbox functions */ + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* MBSE_Reset_Mailbox */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the actual reset mailbox function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* MBS_Reset_Mailbox Actual reset mailbox function*/ +/* */ +/* INPUTS */ +/* */ +/* mailbox_ptr Mailbox control block pointer*/ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_MAILBOX Invalid mailbox supplied */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified interface to exactly */ +/* match prototype, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS MBSE_Reset_Mailbox(NU_MAILBOX *mailbox_ptr) +{ + +MB_MCB *mailbox; /* Mailbox control block ptr */ +STATUS status; /* Completion status */ + + + /* Move input mailbox pointer into internal pointer. */ + mailbox = (MB_MCB *) mailbox_ptr; + + /* Determine if the mailbox pointer is valid. */ + if ((mailbox) && (mailbox -> mb_id == MB_MAILBOX_ID)) + + /* Mailbox pointer is valid, call function to reset it. */ + status = MBS_Reset_Mailbox(mailbox_ptr); + + else + + /* Mailbox pointer is invalid, indicate in completion status. */ + status = NU_INVALID_MAILBOX; + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* MBSE_Broadcast_To_Mailbox */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the mailbox broadcast function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* MBS_Broadcast_To_Mailbox Actual broadcast mailbox func*/ +/* TCCE_Suspend_Error Check suspend validity */ +/* */ +/* INPUTS */ +/* */ +/* mailbox_ptr Mailbox control block pointer*/ +/* message Pointer to message to send */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_MAILBOX Mailbox pointer is invalid */ +/* NU_INVALID_POINTER Message pointer is invalid */ +/* NU_INVALID_SUSPEND Invalid suspend request */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified interface to exactly */ +/* match prototype, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS MBSE_Broadcast_To_Mailbox(NU_MAILBOX *mailbox_ptr, VOID *message, + UNSIGNED suspend) +{ + +MB_MCB *mailbox; /* Mailbox control block ptr */ +STATUS status; /* Completion status */ + + + + /* Move input mailbox pointer into internal pointer. */ + mailbox = (MB_MCB *) mailbox_ptr; + + /* Determine if mailbox pointer is invalid. */ + if (mailbox == NU_NULL) + + /* Mailbox pointer is invalid, indicate in completion status. */ + status = NU_INVALID_MAILBOX; + + else if (mailbox -> mb_id != MB_MAILBOX_ID) + + /* Mailbox pointer is invalid, indicate in completion status. */ + status = NU_INVALID_MAILBOX; + + else if (message == NU_NULL) + + /* Message pointer is invalid, indicate in completion status. */ + status = NU_INVALID_POINTER; + + else if ((suspend) && (TCCE_Suspend_Error())) + + /* Indicate that suspension is only valid from a task thread. */ + status = NU_INVALID_SUSPEND; + + else + + /* Parameters are valid, call actual function. */ + status = MBS_Broadcast_To_Mailbox(mailbox_ptr, message, suspend); + + /* Return the completion status. */ + return(status); +} + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/nucleus.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,1226 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* nucleus.h Nucleus PLUS\ARM925\Code Composer 1.14.1 */ +/* */ +/* COMPONENT */ +/* */ +/* System Constants */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains system constants common to both the */ +/* application and the actual Nucleus PLUS components. This file */ +/* also contains data structure definitions that hide internal */ +/* information from the application. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* NU_DRIVER I/O Driver control block */ +/* NU_EVENT_GROUP Event group control block */ +/* NU_HISR HISR control block */ +/* NU_MAILBOX Mailbox control block */ +/* NU_MEMORY_POOL Memory Pool control block */ +/* NU_PARTITION_POOL Partition Pool control block */ +/* NU_PIPE Pipe control block */ +/* NU_QUEUE Queue control block */ +/* NU_SEMAPHORE Semaphore control block */ +/* NU_TASK Task control block */ +/* NU_TIMER Timer control block */ +/* NU_PROTECT Protection structure */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* NAME DATE REMARKS */ +/* */ +/* B. Ronquillo 08-28-2002 Released version 1.14.1 */ +/* */ +/* */ +/*************************************************************************/ + +/* Check to see if this file has been included already. */ + +#ifndef NUCLEUS + +#ifdef __cplusplus +extern "C" { /* C declarations in C++ */ +#endif + +#define NUCLEUS + +#define PLUS_1_11 1 +#define PLUS_1_13 2 +#define PLUS_1_14 3 +#define PLUS_VERSION_COMP PLUS_1_14 + +#ifndef NU_SUPERV_USER_MODE +#define NU_SUPERV_USER_MODE 0 +#endif + +#ifndef NU_MODULE_SUPPORT +#define NU_MODULE_SUPPORT 0 +#endif + +#ifndef NU_MMU_MODE +#define NU_MMU_MODE 0 +#endif + +/* + * The original version of this file in XVilka's code drop contained + * some definitions specific to the OMAP1510 platform targeted by that + * code drop. Nothing else in this package uses these definitions, + * though, so I have decided that the best thing to do is to simply + * eliminate them altogether. -- Spacefalcon the Outlaw + */ + +#if 0 + +/* Define the clock frequency that is used by the timer control unit (must be defined in hertz */ +#define NU_System_Clock_Frequency 84000000 + +/* Define the number of Nucleus PLUS ticks that will occur every second */ +#define NU_PLUS_Ticks_Per_Second 100 + +/* Define the number of timer ticks that will occur every second. This is + usually the frequency of the timer used by the Nucleus clock. It may + be modified by a prescalar. See the INT assembler file for more info */ + +#define NU_HW_Ticks_Per_Second (NU_System_Clock_Frequency) + +/* The number of timer ticks between Nucleus timer interrupts that increment + TMD_System_Clock. See timer initialization code for details about how to + determine this number. */ +#define NU_HW_Ticks_Per_SW_Tick (NU_HW_Ticks_Per_Second / NU_PLUS_Ticks_Per_Second) + +/* Define NU_COUNT_DOWN if the system timer counts down to 0. + This macro is used to switch between formulas to calculate + the number of ticks since the systems started in NU_Get_Clock */ +#define NU_COUNT_DOWN + +/* This macro returns the value of the Nucleus timer (not the system clock) */ +#define NU_Retrieve_Hardware_Clock(hw_tick) hw_tick = *(UINT32 *)(0xFFFEC608) + +#endif + +/* Define standard data types. These definitions allow Nucleus PLUS to + perform in the same manner on different target platforms. */ + +typedef unsigned long UNSIGNED; +typedef long SIGNED; +typedef unsigned char DATA_ELEMENT; +typedef DATA_ELEMENT OPTION; +typedef int STATUS; +typedef unsigned char UNSIGNED_CHAR; +typedef char CHAR; +typedef int INT; +typedef unsigned long * UNSIGNED_PTR; +typedef unsigned char * BYTE_PTR; +typedef DATA_ELEMENT BOOLEAN; +typedef unsigned int UNSIGNED_INT; + +#define VOID void +#define HUGE +#define FAR + +typedef char INT8; +typedef unsigned char UINT8; +typedef signed short INT16; +typedef unsigned short UINT16; +typedef signed long INT32; +typedef unsigned long UINT32; + + +/* Define register defines. R1, R2, R3, and R4 are used in the Nucleus PLUS + source code in front of variables that are referenced often. In some + ports, defining them as "register" will improve performance. */ + +#define R1 register +#define R2 register +#define R3 register +#define R4 register + + +/* Define the number of accesses required to read or write a pointer data + type. This value is used to make optimizations in some ports of Nucleus + PLUS. */ + +#define NU_POINTER_ACCESS 1 + + +/* Define the padding required for usage of the DATA_ELEMENT type within + Nucleus PLUS structures. These values insure proper alignment for the + next structure member. */ + +#define PAD_1 3 +#define PAD_2 2 +#define PAD_3 1 + + + +/* Define constants that are target dependent and/or are used for internal + purposes. */ + +#define NU_MIN_STACK_SIZE 240 +#define NU_MAX_NAME 8 +#define NU_MAX_VECTORS 64 +#define NU_MAX_LISRS 8 + + +/* Define constants for the number of UNSIGNED words in each of the basic + system data structures. */ + +#define NU_TASK_SIZE 42 +#define NU_HISR_SIZE 22 +#define NU_MAILBOX_SIZE 13 +#define NU_QUEUE_SIZE 18 +#define NU_PIPE_SIZE 18 +#define NU_SEMAPHORE_SIZE 10 +#define NU_EVENT_GROUP_SIZE 9 +#define NU_PARTITION_POOL_SIZE 15 +#define NU_MEMORY_POOL_SIZE 17 +#define NU_TIMER_SIZE 17 +#define NU_PROTECT_SIZE 2 +#define NU_DRIVER_SIZE 3 + +/* Define what an interrupt vector looks like on the target processor. */ + +typedef struct NU_VECTOR_STRUCT +{ + VOID *pointer; +} NU_VECTOR; + + +/* Define constants for use in service parameters. */ + +#define NU_AND 2 +#define NU_AND_CONSUME 3 +#define NU_DISABLE_TIMER 4 +#define NU_ENABLE_TIMER 5 +#define NU_FALSE 0 +#define NU_FIFO 6 +#define NU_FIXED_SIZE 7 +#define NU_NO_PREEMPT 8 +#define NU_NO_START 9 +#define NU_NO_SUSPEND 0 +#define NU_NULL 0 +#define NU_OR 0 +#define NU_OR_CONSUME 1 +#define NU_PREEMPT 10 +#define NU_PRIORITY 11 +#define NU_START 12 +#define NU_SUSPEND 0xFFFFFFFFUL +#define NU_TRUE 1 +#define NU_VARIABLE_SIZE 13 + + +/* Define interrupt lockout and enable constants. */ + +#define NU_DISABLE_INTERRUPTS 0xC0 +#define NU_ENABLE_INTERRUPTS 0x00 + + +/* Define task suspension constants. */ + +#define NU_DRIVER_SUSPEND 10 +#define NU_EVENT_SUSPEND 7 +#define NU_FINISHED 11 +#define NU_MAILBOX_SUSPEND 3 +#define NU_MEMORY_SUSPEND 9 +#define NU_PARTITION_SUSPEND 8 +#define NU_PIPE_SUSPEND 5 +#define NU_PURE_SUSPEND 1 +#define NU_QUEUE_SUSPEND 4 +#define NU_READY 0 +#define NU_SEMAPHORE_SUSPEND 6 +#define NU_SLEEP_SUSPEND 2 +#define NU_TERMINATED 12 + +/* Define service completion status constants. */ + +#define NU_SUCCESS 0 +#define NU_END_OF_LOG -1 +#define NU_GROUP_DELETED -2 +#define NU_INVALID_DELETE -3 +#define NU_INVALID_DRIVER -4 +#define NU_INVALID_ENABLE -5 +#define NU_INVALID_ENTRY -6 +#define NU_INVALID_FUNCTION -7 +#define NU_INVALID_GROUP -8 +#define NU_INVALID_HISR -9 +#define NU_INVALID_MAILBOX -10 +#define NU_INVALID_MEMORY -11 +#define NU_INVALID_MESSAGE -12 +#define NU_INVALID_OPERATION -13 +#define NU_INVALID_PIPE -14 +#define NU_INVALID_POINTER -15 +#define NU_INVALID_POOL -16 +#define NU_INVALID_PREEMPT -17 +#define NU_INVALID_PRIORITY -18 +#define NU_INVALID_QUEUE -19 +#define NU_INVALID_RESUME -20 +#define NU_INVALID_SEMAPHORE -21 +#define NU_INVALID_SIZE -22 +#define NU_INVALID_START -23 +#define NU_INVALID_SUSPEND -24 +#define NU_INVALID_TASK -25 +#define NU_INVALID_TIMER -26 +#define NU_INVALID_VECTOR -27 +#define NU_MAILBOX_DELETED -28 +#define NU_MAILBOX_EMPTY -29 +#define NU_MAILBOX_FULL -30 +#define NU_MAILBOX_RESET -31 +#define NU_NO_MEMORY -32 +#define NU_NO_MORE_LISRS -33 +#define NU_NO_PARTITION -34 +#define NU_NOT_DISABLED -35 +#define NU_NOT_PRESENT -36 +#define NU_NOT_REGISTERED -37 +#define NU_NOT_TERMINATED -38 +#define NU_PIPE_DELETED -39 +#define NU_PIPE_EMPTY -40 +#define NU_PIPE_FULL -41 +#define NU_PIPE_RESET -42 +#define NU_POOL_DELETED -43 +#define NU_QUEUE_DELETED -44 +#define NU_QUEUE_EMPTY -45 +#define NU_QUEUE_FULL -46 +#define NU_QUEUE_RESET -47 +#define NU_SEMAPHORE_DELETED -48 +#define NU_SEMAPHORE_RESET -49 +#define NU_TIMEOUT -50 +#define NU_UNAVAILABLE -51 +#define NU_INVALID_DESCRIPTION -52 +#define NU_INVALID_REGION -53 +#define NU_MEMORY_CORRUPT -54 +#define NU_INVALID_DEBUG_ALLOCATION -55 +#define NU_EMPTY_DEBUG_ALLOCATION_LIST -56 + + + +/* Define system errors. */ + +#define NU_ERROR_CREATING_TIMER_HISR 1 +#define NU_ERROR_CREATING_TIMER_TASK 2 +#define NU_STACK_OVERFLOW 3 +#define NU_UNHANDLED_INTERRUPT 4 + + +/* Define I/O driver constants. */ + +#define NU_IO_ERROR -1 +#define NU_INITIALIZE 1 +#define NU_ASSIGN 2 +#define NU_RELEASE 3 +#define NU_INPUT 4 +#define NU_OUTPUT 5 +#define NU_STATUS 6 +#define NU_TERMINATE 7 + + +/* Define history entry IDs. */ + +#define NU_USER_ID 1 +#define NU_CREATE_TASK_ID 2 +#define NU_DELETE_TASK_ID 3 +#define NU_RESET_TASK_ID 4 +#define NU_TERMINATE_TASK_ID 5 +#define NU_RESUME_TASK_ID 6 +#define NU_SUSPEND_TASK_ID 7 +#define NU_RELINQUISH_ID 8 +#define NU_SLEEP_ID 9 +#define NU_CHANGE_PRIORITY_ID 10 +#define NU_CHANGE_PREEMPTION_ID 11 +#define NU_CREATE_MAILBOX_ID 12 +#define NU_DELETE_MAILBOX_ID 13 +#define NU_RESET_MAILBOX_ID 14 +#define NU_SEND_TO_MAILBOX_ID 15 +#define NU_BROADCAST_TO_MAILBOX_ID 16 +#define NU_RECEIVE_FROM_MAILBOX_ID 17 +#define NU_CREATE_QUEUE_ID 18 +#define NU_DELETE_QUEUE_ID 19 +#define NU_RESET_QUEUE_ID 20 +#define NU_SEND_TO_FRONT_OF_QUEUE_ID 21 +#define NU_SEND_TO_QUEUE_ID 22 +#define NU_BROADCAST_TO_QUEUE_ID 23 +#define NU_RECEIVE_FROM_QUEUE_ID 24 +#define NU_CREATE_PIPE_ID 25 +#define NU_DELETE_PIPE_ID 26 +#define NU_RESET_PIPE_ID 27 +#define NU_SEND_TO_FRONT_OF_PIPE_ID 28 +#define NU_SEND_TO_PIPE_ID 29 +#define NU_BROADCAST_TO_PIPE_ID 30 +#define NU_RECEIVE_FROM_PIPE_ID 31 +#define NU_CREATE_SEMAPHORE_ID 32 +#define NU_DELETE_SEMAPHORE_ID 33 +#define NU_RESET_SEMAPHORE_ID 34 +#define NU_OBTAIN_SEMAPHORE_ID 35 +#define NU_RELEASE_SEMAPHORE_ID 36 +#define NU_CREATE_EVENT_GROUP_ID 37 +#define NU_DELETE_EVENT_GROUP_ID 38 +#define NU_SET_EVENTS_ID 39 +#define NU_RETRIEVE_EVENTS_ID 40 +#define NU_CREATE_PARTITION_POOL_ID 41 +#define NU_DELETE_PARTITION_POOL_ID 42 +#define NU_ALLOCATE_PARTITION_ID 43 +#define NU_DEALLOCATE_PARTITION_ID 44 +#define NU_CREATE_MEMORY_POOL_ID 45 +#define NU_DELETE_MEMORY_POOL_ID 46 +#define NU_ALLOCATE_MEMORY_ID 47 +#define NU_DEALLOCATE_MEMORY_ID 48 +#define NU_CONTROL_SIGNALS_ID 49 +#define NU_RECEIVE_SIGNALS_ID 50 +#define NU_REGISTER_SIGNAL_HANDLER_ID 51 +#define NU_SEND_SIGNALS_ID 52 +#define NU_REGISTER_LISR_ID 53 +#define NU_CREATE_HISR_ID 54 +#define NU_DELETE_HISR_ID 55 +#define NU_CREATE_TIMER_ID 56 +#define NU_DELETE_TIMER_ID 57 +#define NU_CONTROL_TIMER_ID 58 +#define NU_RESET_TIMER_ID 59 +#define NU_CREATE_DRIVER_ID 60 +#define NU_DELETE_DRIVER_ID 61 +#define NU_REQUEST_DRIVER_ID 62 +#define NU_RESUME_DRIVER_ID 63 +#define NU_SUSPEND_DRIVER_ID 64 +#define NU_CHANGE_TIME_SLICE_ID 65 +#define NU_ASSERT_ID 66 +#define NU_ALLOCATE_ALIGNED_ID 67 + + +/* Define the basic data structure templates. If the NU_DEBUG conditional + compilation is specified, the actual structure definition is used. */ + +#ifdef NU_DEBUG +#include "cs_defs.h" +#include "tm_defs.h" +#include "tc_defs.h" +#include "mb_defs.h" +#include "qu_defs.h" +#include "pi_defs.h" +#include "sm_defs.h" +#include "ev_defs.h" +#include "pm_defs.h" +#include "dm_defs.h" +#endif + + +#ifndef NU_DEBUG + +/* Define task control data structure with all internal information + hidden. */ +typedef struct NU_TASK_STRUCT +{ + UNSIGNED words[NU_TASK_SIZE]; +} NU_TASK; +#else + +/* Define task control data structure with the actual internal data + structure. */ +typedef TC_TCB NU_TASK; +#endif + + +#ifndef NU_DEBUG + +/* Define HISR control data structure with all internal information + hidden. */ +typedef struct NU_HISR_STRUCT +{ + UNSIGNED words[NU_HISR_SIZE]; +} NU_HISR; +#else + +/* Define HISR control data structure with the actual internal data + structure. */ +typedef TC_HCB NU_HISR; +#endif + + +#ifndef NU_DEBUG + +/* Define mailbox control data structure with all internal information + hidden. */ +typedef struct NU_MAILBOX_STRUCT +{ + UNSIGNED words[NU_MAILBOX_SIZE]; +} NU_MAILBOX; +#else + +/* Define mailbox control data structure with the actual internal data + structure. */ +typedef MB_MCB NU_MAILBOX; +#endif + + +#ifndef NU_DEBUG + +/* Define queue control data structure with all internal information + hidden. */ +typedef struct NU_QUEUE_STRUCT +{ + UNSIGNED words[NU_QUEUE_SIZE]; +} NU_QUEUE; +#else + +/* Define queue control data structure with the actual internal data + structure. */ +typedef QU_QCB NU_QUEUE; +#endif + + +#ifndef NU_DEBUG + +/* Define pipe control data structure with all internal information + hidden. */ +typedef struct NU_PIPE_STRUCT +{ + UNSIGNED words[NU_PIPE_SIZE]; +} NU_PIPE; +#else + +/* Define pipe control data structure with the actual internal data + structure. */ +typedef PI_PCB NU_PIPE; +#endif + + +#ifndef NU_DEBUG + +/* Define semaphore control data structure with all internal information + hidden. */ +typedef struct NU_SEMAPHORE_STRUCT +{ + UNSIGNED words[NU_SEMAPHORE_SIZE]; +} NU_SEMAPHORE; +#else + +/* Define semaphore control data structure with the actual internal data + structure. */ +typedef SM_SCB NU_SEMAPHORE; +#endif + + +#ifndef NU_DEBUG + +/* Define event group control data structure with all internal information + hidden. */ +typedef struct NU_EVENT_GROUP_STRUCT +{ + UNSIGNED words[NU_EVENT_GROUP_SIZE]; +} NU_EVENT_GROUP; +#else + +/* Define event group control data structure with the actual internal data + structure. */ +typedef EV_GCB NU_EVENT_GROUP; +#endif + + +#ifndef NU_DEBUG + +/* Define partition pool control data structure with all internal + information hidden. */ +typedef struct NU_PARTITION_POOL_STRUCT +{ + UNSIGNED words[NU_PARTITION_POOL_SIZE]; +} NU_PARTITION_POOL; +#else + +/* Define partition pool control data structure with the actual internal + data structure. */ +typedef PM_PCB NU_PARTITION_POOL; +#endif + + +#ifndef NU_DEBUG + +/* Define memory pool control data structure with all internal information + hidden. */ +typedef struct NU_MEMORY_POOL_STRUCT +{ + UNSIGNED words[NU_MEMORY_POOL_SIZE]; +} NU_MEMORY_POOL; +#else + +/* Define memory pool control data structure with the actual internal data + structure. */ +typedef DM_PCB NU_MEMORY_POOL; +#endif + + +#ifndef NU_DEBUG + +/* Define timer control data structure with all internal information + hidden. */ +typedef struct NU_TIMER_STRUCT +{ + UNSIGNED words[NU_TIMER_SIZE]; +} NU_TIMER; +#else + +/* Define timer control data structure with the actual internal data + structure. */ +typedef TM_APP_TCB NU_TIMER; +#endif + + +#ifndef NU_DEBUG + +/* Define protect control data structure with all internal information + hidden. */ +typedef struct NU_PROTECT_STRUCT +{ + UNSIGNED words[NU_PROTECT_SIZE]; +} NU_PROTECT; +#else + +/* Define protect control data structure with the actual internal data + structure. */ +typedef TC_PROTECT NU_PROTECT; +#endif + + + +/* Define I/O driver request structures. */ + +struct NU_INITIALIZE_STRUCT +{ + VOID *nu_io_address; /* Base IO address */ + UNSIGNED nu_logical_units; /* Number of logical units */ + VOID *nu_memory; /* Generic memory pointer */ + INT nu_vector; /* Interrupt vector number */ +}; + +struct NU_ASSIGN_STRUCT +{ + UNSIGNED nu_logical_unit; /* Logical unit number */ + INT nu_assign_info; /* Additional assign info */ +}; + +struct NU_RELEASE_STRUCT +{ + UNSIGNED nu_logical_unit; /* Logical unit number */ + INT nu_release_info; /* Additional release info */ +}; + +struct NU_INPUT_STRUCT +{ + UNSIGNED nu_logical_unit; /* Logical unit number */ + UNSIGNED nu_offset; /* Offset of input */ + UNSIGNED nu_request_size; /* Requested input size */ + UNSIGNED nu_actual_size; /* Actual input size */ + VOID *nu_buffer_ptr; /* Input buffer pointer */ +}; + +struct NU_OUTPUT_STRUCT +{ + UNSIGNED nu_logical_unit; /* Logical unit number */ + UNSIGNED nu_offset; /* Offset of output */ + UNSIGNED nu_request_size; /* Requested output size */ + UNSIGNED nu_actual_size; /* Actual output size */ + VOID *nu_buffer_ptr; /* Output buffer pointer */ +}; + +struct NU_STATUS_STRUCT +{ + UNSIGNED nu_logical_unit; /* Logical unit number */ + VOID *nu_extra_status; /* Additional status ptr */ +}; + +struct NU_TERMINATE_STRUCT +{ + UNSIGNED nu_logical_unit; /* Logical unit number */ +}; + + +typedef union NU_REQUEST_INFO_UNION +{ + struct NU_INITIALIZE_STRUCT nu_initialize; + struct NU_ASSIGN_STRUCT nu_assign; + struct NU_RELEASE_STRUCT nu_release; + struct NU_INPUT_STRUCT nu_input; + struct NU_OUTPUT_STRUCT nu_output; + struct NU_STATUS_STRUCT nu_status; + struct NU_TERMINATE_STRUCT nu_terminate; +} nu_request_info_union; + +typedef struct NU_DRIVER_REQUEST_STRUCT +{ + INT nu_function; /* I/O request function */ + UNSIGNED nu_timeout; /* Timeout on request */ + STATUS nu_status; /* Status of request */ + UNSIGNED nu_supplemental; /* Supplemental information */ + VOID *nu_supplemental_ptr; /* Supplemental info pointer*/ + nu_request_info_union nu_request_info; + +} NU_DRIVER_REQUEST; + +typedef struct NU_DRIVER_STRUCT +{ + UNSIGNED words[NU_DRIVER_SIZE]; /* CS_NODE_STRUCT */ + CHAR nu_driver_name[NU_MAX_NAME]; + VOID *nu_info_ptr; + UNSIGNED nu_driver_id; + VOID (*nu_driver_entry)(struct NU_DRIVER_STRUCT *, + NU_DRIVER_REQUEST *); +} NU_DRIVER; + + +/* Define Nucleus PLUS system interfaces. */ + +VOID Application_Initialize(VOID *first_available_memory); + + +/* The following area is only applicable to application files and is skipped + during compilation of Nucleus PLUS source files. */ +#ifndef NU_SOURCE_FILE + +/* Re-map task control functions depending on whether or not error checking + is specified. */ + +#ifdef NU_NO_ERROR_CHECKING +#define NU_Create_Task TCC_Create_Task +#define NU_Delete_Task TCC_Delete_Task +#define NU_Reset_Task TCC_Reset_Task +#define NU_Terminate_Task TCC_Terminate_Task +#define NU_Resume_Task TCC_Resume_Service +#define NU_Suspend_Task TCC_Suspend_Service +#define NU_Relinquish TCC_Relinquish +#define NU_Sleep TCC_Task_Sleep +#define NU_Change_Priority TCS_Change_Priority +#define NU_Change_Preemption TCS_Change_Preemption +#define NU_Change_Time_Slice TCS_Change_Time_Slice +#define NU_Check_Stack TCT_Check_Stack +#define NU_Current_Task_Pointer TCC_Current_Task_Pointer +#define NU_Established_Tasks TCF_Established_Tasks +#define NU_Task_Information TCF_Task_Information +#define NU_Task_Pointers TCF_Task_Pointers +#define NU_Create_Mailbox MBC_Create_Mailbox +#define NU_Delete_Mailbox MBC_Delete_Mailbox +#define NU_Reset_Mailbox MBS_Reset_Mailbox +#define NU_Send_To_Mailbox MBC_Send_To_Mailbox +#define NU_Broadcast_To_Mailbox MBS_Broadcast_To_Mailbox +#define NU_Receive_From_Mailbox MBC_Receive_From_Mailbox +#define NU_Established_Mailboxes MBF_Established_Mailboxes +#define NU_Mailbox_Information MBF_Mailbox_Information +#define NU_Mailbox_Pointers MBF_Mailbox_Pointers +#define NU_Create_Queue QUC_Create_Queue +#define NU_Delete_Queue QUC_Delete_Queue +#define NU_Reset_Queue QUS_Reset_Queue +#define NU_Send_To_Front_Of_Queue QUS_Send_To_Front_Of_Queue +#define NU_Send_To_Queue QUC_Send_To_Queue +#define NU_Broadcast_To_Queue QUS_Broadcast_To_Queue +#define NU_Receive_From_Queue QUC_Receive_From_Queue +#define NU_Established_Queues QUF_Established_Queues +#define NU_Queue_Information QUF_Queue_Information +#define NU_Queue_Pointers QUF_Queue_Pointers +#define NU_Create_Pipe PIC_Create_Pipe +#define NU_Delete_Pipe PIC_Delete_Pipe +#define NU_Reset_Pipe PIS_Reset_Pipe +#define NU_Send_To_Front_Of_Pipe PIS_Send_To_Front_Of_Pipe +#define NU_Send_To_Pipe PIC_Send_To_Pipe +#define NU_Broadcast_To_Pipe PIS_Broadcast_To_Pipe +#define NU_Receive_From_Pipe PIC_Receive_From_Pipe +#define NU_Established_Pipes PIF_Established_Pipes +#define NU_Pipe_Information PIF_Pipe_Information +#define NU_Pipe_Pointers PIF_Pipe_Pointers +#define NU_Create_Semaphore SMC_Create_Semaphore +#define NU_Delete_Semaphore SMC_Delete_Semaphore +#define NU_Reset_Semaphore SMS_Reset_Semaphore +#define NU_Obtain_Semaphore SMC_Obtain_Semaphore +#define NU_Release_Semaphore SMC_Release_Semaphore +#define NU_Established_Semaphores SMF_Established_Semaphores +#define NU_Semaphore_Information SMF_Semaphore_Information +#define NU_Semaphore_Pointers SMF_Semaphore_Pointers +#define NU_Create_Event_Group EVC_Create_Event_Group +#define NU_Delete_Event_Group EVC_Delete_Event_Group +#define NU_Set_Events EVC_Set_Events +#define NU_Retrieve_Events EVC_Retrieve_Events +#define NU_Established_Event_Groups EVF_Established_Event_Groups +#define NU_Event_Group_Information EVF_Event_Group_Information +#define NU_Event_Group_Pointers EVF_Event_Group_Pointers +#define NU_Create_Partition_Pool PMC_Create_Partition_Pool +#define NU_Delete_Partition_Pool PMC_Delete_Partition_Pool +#define NU_Allocate_Partition PMC_Allocate_Partition +#define NU_Deallocate_Partition PMC_Deallocate_Partition +#define NU_Established_Partition_Pools PMF_Established_Partition_Pools +#define NU_Partition_Pool_Information PMF_Partition_Pool_Information +#define NU_Partition_Pool_Pointers PMF_Partition_Pool_Pointers +#define NU_Create_Memory_Pool DMC_Create_Memory_Pool +#define NU_Delete_Memory_Pool DMC_Delete_Memory_Pool +#define NU_Allocate_Memory DMC_Allocate_Memory +#define NU_Deallocate_Memory DMC_Deallocate_Memory +#define NU_Established_Memory_Pools DMF_Established_Memory_Pools +#define NU_Memory_Pool_Information DMF_Memory_Pool_Information +#define NU_Memory_Pool_Pointers DMF_Memory_Pool_Pointers +#define NU_Control_Signals TCS_Control_Signals +#define NU_Receive_Signals TCS_Receive_Signals +#define NU_Register_Signal_Handler TCS_Register_Signal_Handler +#define NU_Send_Signals TCS_Send_Signals +#define NU_Setup_Vector INT_Setup_Vector +#define NU_Register_LISR TCC_Register_LISR +#define NU_Activate_HISR TCT_Activate_HISR +#define NU_Create_HISR TCC_Create_HISR +#define NU_Delete_HISR TCC_Delete_HISR +#define NU_Current_HISR_Pointer TCC_Current_HISR_Pointer +#define NU_Established_HISRs TCF_Established_HISRs +#define NU_HISR_Pointers TCF_HISR_Pointers +#define NU_HISR_Information TCF_HISR_Information +#define NU_Protect TCT_Protect +#define NU_Unprotect TCT_Unprotect +#define NU_Control_Interrupts TCT_Control_Interrupts +#define NU_Local_Control_Interrupts TCT_Local_Control_Interrupts +#define NU_Restore_Interrupts TCT_Restore_Interrupts +#define NU_Set_Clock TMT_Set_Clock +#define NU_Retrieve_Clock TMT_Retrieve_Clock +#define NU_Create_Timer TMS_Create_Timer +#define NU_Delete_Timer TMS_Delete_Timer +#define NU_Control_Timer TMS_Control_Timer +#define NU_Reset_Timer TMS_Reset_Timer +#define NU_Established_Timers TMF_Established_Timers +#define NU_Timer_Pointers TMF_Timer_Pointers +#define NU_Timer_Information TMF_Timer_Information +#define NU_Get_Remaining_Time TMF_Get_Remaining_Time +#define NU_Release_Information RLC_Release_Information +#define NU_License_Information LIC_License_Information +#define NU_Disable_History_Saving HIC_Disable_History_Saving +#define NU_Enable_History_Saving HIC_Enable_History_Saving +#define NU_Make_History_Entry HIC_Make_History_Entry_Service +#define NU_Retrieve_History_Entry HIC_Retrieve_History_Entry +#define NU_Create_Driver IOC_Create_Driver +#define NU_Delete_Driver IOC_Delete_Driver +#define NU_Request_Driver IOC_Request_Driver +#define NU_Resume_Driver IOC_Resume_Driver +#define NU_Suspend_Driver IOC_Suspend_Driver +#define NU_Established_Drivers IOF_Established_Drivers +#define NU_Driver_Pointers IOF_Driver_Pointers +#else +#define NU_Create_Task TCCE_Create_Task +#define NU_Delete_Task TCCE_Delete_Task +#define NU_Reset_Task TCCE_Reset_Task +#define NU_Terminate_Task TCCE_Terminate_Task +#define NU_Resume_Task TCCE_Resume_Service +#define NU_Suspend_Task TCCE_Suspend_Service +#define NU_Relinquish TCCE_Relinquish +#define NU_Sleep TCCE_Task_Sleep +#define NU_Change_Priority TCSE_Change_Priority +#define NU_Change_Preemption TCSE_Change_Preemption +#define NU_Change_Time_Slice TCSE_Change_Time_Slice +#define NU_Check_Stack TCT_Check_Stack +#define NU_Current_Task_Pointer TCC_Current_Task_Pointer +#define NU_Established_Tasks TCF_Established_Tasks +#define NU_Task_Information TCFE_Task_Information +#define NU_Task_Pointers TCF_Task_Pointers +#define NU_Create_Mailbox MBCE_Create_Mailbox +#define NU_Delete_Mailbox MBCE_Delete_Mailbox +#define NU_Reset_Mailbox MBSE_Reset_Mailbox +#define NU_Send_To_Mailbox MBCE_Send_To_Mailbox +#define NU_Broadcast_To_Mailbox MBSE_Broadcast_To_Mailbox +#define NU_Receive_From_Mailbox MBCE_Receive_From_Mailbox +#define NU_Established_Mailboxes MBF_Established_Mailboxes +#define NU_Mailbox_Information MBF_Mailbox_Information +#define NU_Mailbox_Pointers MBF_Mailbox_Pointers +#define NU_Create_Queue QUCE_Create_Queue +#define NU_Delete_Queue QUCE_Delete_Queue +#define NU_Reset_Queue QUSE_Reset_Queue +#define NU_Send_To_Queue QUCE_Send_To_Queue +#define NU_Send_To_Front_Of_Queue QUSE_Send_To_Front_Of_Queue +#define NU_Broadcast_To_Queue QUSE_Broadcast_To_Queue +#define NU_Receive_From_Queue QUCE_Receive_From_Queue +#define NU_Established_Queues QUF_Established_Queues +#define NU_Queue_Information QUF_Queue_Information +#define NU_Queue_Pointers QUF_Queue_Pointers +#define NU_Create_Pipe PICE_Create_Pipe +#define NU_Delete_Pipe PICE_Delete_Pipe +#define NU_Reset_Pipe PISE_Reset_Pipe +#define NU_Send_To_Front_Of_Pipe PISE_Send_To_Front_Of_Pipe +#define NU_Send_To_Pipe PICE_Send_To_Pipe +#define NU_Broadcast_To_Pipe PISE_Broadcast_To_Pipe +#define NU_Receive_From_Pipe PICE_Receive_From_Pipe +#define NU_Established_Pipes PIF_Established_Pipes +#define NU_Pipe_Information PIF_Pipe_Information +#define NU_Pipe_Pointers PIF_Pipe_Pointers +#define NU_Create_Semaphore SMCE_Create_Semaphore +#define NU_Delete_Semaphore SMCE_Delete_Semaphore +#define NU_Reset_Semaphore SMSE_Reset_Semaphore +#define NU_Obtain_Semaphore SMCE_Obtain_Semaphore +#define NU_Release_Semaphore SMCE_Release_Semaphore +#define NU_Established_Semaphores SMF_Established_Semaphores +#define NU_Semaphore_Information SMF_Semaphore_Information +#define NU_Semaphore_Pointers SMF_Semaphore_Pointers +#define NU_Create_Event_Group EVCE_Create_Event_Group +#define NU_Delete_Event_Group EVCE_Delete_Event_Group +#define NU_Set_Events EVCE_Set_Events +#define NU_Retrieve_Events EVCE_Retrieve_Events +#define NU_Established_Event_Groups EVF_Established_Event_Groups +#define NU_Event_Group_Information EVF_Event_Group_Information +#define NU_Event_Group_Pointers EVF_Event_Group_Pointers +#define NU_Create_Partition_Pool PMCE_Create_Partition_Pool +#define NU_Delete_Partition_Pool PMCE_Delete_Partition_Pool +#define NU_Allocate_Partition PMCE_Allocate_Partition +#define NU_Deallocate_Partition PMCE_Deallocate_Partition +#define NU_Established_Partition_Pools PMF_Established_Partition_Pools +#define NU_Partition_Pool_Information PMF_Partition_Pool_Information +#define NU_Partition_Pool_Pointers PMF_Partition_Pool_Pointers +#define NU_Create_Memory_Pool DMCE_Create_Memory_Pool +#define NU_Delete_Memory_Pool DMCE_Delete_Memory_Pool + +/* The following conditional routes memory allocation calls to functions + that help track memory leaks. */ +#ifdef NU_DEBUG_MEMORY +#define NU_Deallocate_Memory ERC_Deallocate_Memory +#else +#define NU_Deallocate_Memory DMCE_Deallocate_Memory +#endif /* NU_DEBUG_MEMORY */ + +#define NU_Established_Memory_Pools DMF_Established_Memory_Pools +#define NU_Memory_Pool_Information DMF_Memory_Pool_Information +#define NU_Memory_Pool_Pointers DMF_Memory_Pool_Pointers +#define NU_Control_Signals TCSE_Control_Signals +#define NU_Receive_Signals TCSE_Receive_Signals +#define NU_Register_Signal_Handler TCSE_Register_Signal_Handler +#define NU_Send_Signals TCSE_Send_Signals +#define NU_Setup_Vector INT_Setup_Vector +#define NU_Register_LISR TCC_Register_LISR +#define NU_Activate_HISR TCCE_Activate_HISR +#define NU_Create_HISR TCCE_Create_HISR +#define NU_Delete_HISR TCCE_Delete_HISR +#define NU_Current_HISR_Pointer TCC_Current_HISR_Pointer +#define NU_Established_HISRs TCF_Established_HISRs +#define NU_HISR_Pointers TCF_HISR_Pointers +#define NU_HISR_Information TCF_HISR_Information +#define NU_Protect TCT_Protect +#define NU_Unprotect TCT_Unprotect +#define NU_Control_Interrupts TCT_Control_Interrupts +#define NU_Local_Control_Interrupts TCT_Local_Control_Interrupts +#define NU_Restore_Interrupts TCT_Restore_Interrupts +#define NU_Set_Clock TMT_Set_Clock +#define NU_Retrieve_Clock TMT_Retrieve_Clock +#define NU_Create_Timer TMSE_Create_Timer +#define NU_Delete_Timer TMSE_Delete_Timer +#define NU_Control_Timer TMSE_Control_Timer +#define NU_Reset_Timer TMSE_Reset_Timer +#define NU_Established_Timers TMF_Established_Timers +#define NU_Timer_Pointers TMF_Timer_Pointers +#define NU_Timer_Information TMF_Timer_Information +#define NU_Get_Remaining_Time TMF_Get_Remaining_Time +#define NU_Release_Information RLC_Release_Information +#define NU_License_Information LIC_License_Information +#define NU_Disable_History_Saving HIC_Disable_History_Saving +#define NU_Enable_History_Saving HIC_Enable_History_Saving +#define NU_Make_History_Entry HIC_Make_History_Entry_Service +#define NU_Retrieve_History_Entry HIC_Retrieve_History_Entry +#define NU_Create_Driver IOCE_Create_Driver +#define NU_Delete_Driver IOCE_Delete_Driver +#define NU_Request_Driver IOCE_Request_Driver +#define NU_Resume_Driver IOCE_Resume_Driver +#define NU_Suspend_Driver IOCE_Suspend_Driver +#define NU_Established_Drivers IOF_Established_Drivers +#define NU_Driver_Pointers IOF_Driver_Pointers +#endif + + +/* Define task control functions. */ + +STATUS NU_Create_Task(NU_TASK *task, CHAR *name, + VOID (*task_entry)(UNSIGNED, VOID *), UNSIGNED argc, + VOID *argv, VOID *stack_address, UNSIGNED stack_size, + OPTION priority, UNSIGNED time_slice, + OPTION preempt, OPTION auto_start); +STATUS NU_Delete_Task(NU_TASK *task); +STATUS NU_Reset_Task(NU_TASK *task, UNSIGNED argc, VOID *argv); +STATUS NU_Terminate_Task(NU_TASK *task); +STATUS NU_Resume_Task(NU_TASK *task); +STATUS NU_Suspend_Task(NU_TASK *task); +VOID NU_Relinquish(VOID); +VOID NU_Sleep(UNSIGNED ticks); +OPTION NU_Change_Priority(NU_TASK *task, OPTION new_priority); +OPTION NU_Change_Preemption(OPTION preempt); +UNSIGNED NU_Change_Time_Slice(NU_TASK *task, UNSIGNED time_slice); +UNSIGNED NU_Check_Stack(VOID); +NU_TASK *NU_Current_Task_Pointer(VOID); +UNSIGNED NU_Established_Tasks(VOID); +STATUS NU_Task_Information(NU_TASK *task, CHAR *name, + DATA_ELEMENT *status, UNSIGNED *scheduled_count, + OPTION *priority, OPTION *preempt, + UNSIGNED *time_slice, VOID **stack_base, + UNSIGNED *stack_size, UNSIGNED *minimum_stack); +UNSIGNED NU_Task_Pointers(NU_TASK **pointer_list, + UNSIGNED maximum_pointers); + +/* Define Mailbox management functions. */ + +STATUS NU_Create_Mailbox(NU_MAILBOX *mailbox, CHAR *name, + OPTION suspend_type); +STATUS NU_Delete_Mailbox(NU_MAILBOX *mailbox); +STATUS NU_Reset_Mailbox(NU_MAILBOX *mailbox); +STATUS NU_Send_To_Mailbox(NU_MAILBOX *mailbox, VOID *message, + UNSIGNED suspend); +STATUS NU_Broadcast_To_Mailbox(NU_MAILBOX *mailbox, VOID *message, + UNSIGNED suspend); +STATUS NU_Receive_From_Mailbox(NU_MAILBOX *mailbox, VOID *message, + UNSIGNED suspend); +UNSIGNED NU_Established_Mailboxes(VOID); +STATUS NU_Mailbox_Information(NU_MAILBOX *mailbox, CHAR *name, + OPTION *suspend_type, OPTION *message_present, + UNSIGNED *tasks_waiting, NU_TASK **first_task); +UNSIGNED NU_Mailbox_Pointers(NU_MAILBOX **pointer_list, + UNSIGNED maximum_pointers); + +/* Define Queue management functions. */ + +STATUS NU_Create_Queue(NU_QUEUE *queue, CHAR *name, + VOID *start_address, UNSIGNED queue_size, + OPTION message_type, UNSIGNED message_size, + OPTION suspend_type); +STATUS NU_Delete_Queue(NU_QUEUE *queue); +STATUS NU_Reset_Queue(NU_QUEUE *queue); +STATUS NU_Send_To_Front_Of_Queue(NU_QUEUE *queue, VOID *message, + UNSIGNED size, UNSIGNED suspend); +STATUS NU_Send_To_Queue(NU_QUEUE *queue, VOID *message, + UNSIGNED size, UNSIGNED suspend); +STATUS NU_Broadcast_To_Queue(NU_QUEUE *queue, VOID *message, + UNSIGNED size, UNSIGNED suspend); +STATUS NU_Receive_From_Queue(NU_QUEUE *queue, VOID *message, + UNSIGNED size, UNSIGNED *actual_size, UNSIGNED suspend); +UNSIGNED NU_Established_Queues(VOID); +STATUS NU_Queue_Information(NU_QUEUE *queue, CHAR *name, + VOID **start_address, UNSIGNED *queue_size, + UNSIGNED *available, UNSIGNED *messages, + OPTION *message_type, UNSIGNED *message_size, + OPTION *suspend_type, UNSIGNED *tasks_waiting, + NU_TASK **first_task); +UNSIGNED NU_Queue_Pointers(NU_QUEUE **pointer_list, + UNSIGNED maximum_pointers); + +/* Define Pipe management functions. */ + +STATUS NU_Create_Pipe(NU_PIPE *pipe, CHAR *name, + VOID *start_address, UNSIGNED pipe_size, + OPTION message_type, UNSIGNED message_size, + OPTION suspend_type); +STATUS NU_Delete_Pipe(NU_PIPE *pipe); +STATUS NU_Reset_Pipe(NU_PIPE *pipe); +STATUS NU_Send_To_Front_Of_Pipe(NU_PIPE *pipe, VOID *message, + UNSIGNED size, UNSIGNED suspend); +STATUS NU_Send_To_Pipe(NU_PIPE *pipe, VOID *message, + UNSIGNED size, UNSIGNED suspend); +STATUS NU_Broadcast_To_Pipe(NU_PIPE *pipe, VOID *message, + UNSIGNED size, UNSIGNED suspend); +STATUS NU_Receive_From_Pipe(NU_PIPE *pipe, VOID *message, + UNSIGNED size, UNSIGNED *actual_size, UNSIGNED suspend); +UNSIGNED NU_Established_Pipes(VOID); +STATUS NU_Pipe_Information(NU_PIPE *pipe, CHAR *name, + VOID **start_address, UNSIGNED *pipe_size, + UNSIGNED *available, UNSIGNED *messages, + OPTION *message_type, UNSIGNED *message_size, + OPTION *suspend_type, UNSIGNED *tasks_waiting, + NU_TASK **first_task); +UNSIGNED NU_Pipe_Pointers(NU_PIPE **pointer_list, + UNSIGNED maximum_pointers); + +/* Define Semaphore management functions. */ + +STATUS NU_Create_Semaphore(NU_SEMAPHORE *semaphore, CHAR *name, + UNSIGNED initial_count, OPTION suspend_type); +STATUS NU_Delete_Semaphore(NU_SEMAPHORE *semaphore); +STATUS NU_Reset_Semaphore(NU_SEMAPHORE *semaphore, + UNSIGNED initial_count); +STATUS NU_Obtain_Semaphore(NU_SEMAPHORE *semaphore, UNSIGNED suspend); +STATUS NU_Release_Semaphore(NU_SEMAPHORE *semaphore); +UNSIGNED NU_Established_Semaphores(VOID); +STATUS NU_Semaphore_Information(NU_SEMAPHORE *semaphore, CHAR *name, + UNSIGNED *current_count, OPTION *suspend_type, + UNSIGNED *tasks_waiting, NU_TASK **first_task); +UNSIGNED NU_Semaphore_Pointers(NU_SEMAPHORE **pointer_list, + UNSIGNED maximum_pointers); + +/* Define Event Group management functions. */ + +STATUS NU_Create_Event_Group(NU_EVENT_GROUP *group, CHAR *name); +STATUS NU_Delete_Event_Group(NU_EVENT_GROUP *group); +STATUS NU_Set_Events(NU_EVENT_GROUP *group, UNSIGNED events, + OPTION operation); +STATUS NU_Retrieve_Events(NU_EVENT_GROUP *group, + UNSIGNED requested_flags, OPTION operation, + UNSIGNED *retrieved_flags, UNSIGNED suspend); +UNSIGNED NU_Established_Event_Groups(VOID); +STATUS NU_Event_Group_Information(NU_EVENT_GROUP *group, CHAR *name, + UNSIGNED *event_flags, UNSIGNED *tasks_waiting, + NU_TASK **first_task); +UNSIGNED NU_Event_Group_Pointers(NU_EVENT_GROUP **pointer_list, + UNSIGNED maximum_pointers); + +/* Define Signal processing functions. */ + +UNSIGNED NU_Control_Signals(UNSIGNED signal_enable_mask); +UNSIGNED NU_Receive_Signals(VOID); +STATUS NU_Register_Signal_Handler(VOID (*signal_handler)(UNSIGNED)); +STATUS NU_Send_Signals(NU_TASK *task, UNSIGNED signals); + +/* Define Partition memory management functions. */ + +STATUS NU_Create_Partition_Pool(NU_PARTITION_POOL *pool, CHAR *name, + VOID *start_address, UNSIGNED pool_size, + UNSIGNED partition_size, OPTION suspend_type); +STATUS NU_Delete_Partition_Pool(NU_PARTITION_POOL *pool); +STATUS NU_Allocate_Partition(NU_PARTITION_POOL *pool, + VOID **return_pointer, UNSIGNED suspend); +STATUS NU_Deallocate_Partition(VOID *partition); +UNSIGNED NU_Established_Partition_Pools(VOID); +STATUS NU_Partition_Pool_Information(NU_PARTITION_POOL *pool, + CHAR *name, + VOID **start_address, UNSIGNED *pool_size, + UNSIGNED *partition_size, UNSIGNED *available, + UNSIGNED *allocated, OPTION *suspend_type, + UNSIGNED *tasks_waiting, NU_TASK **first_task); +UNSIGNED NU_Partition_Pool_Pointers(NU_PARTITION_POOL **pointer_list, + UNSIGNED maximum_pointers); + +/* Define Dynamic memory management functions. */ + +STATUS NU_Create_Memory_Pool(NU_MEMORY_POOL *pool, CHAR *name, + VOID *start_address, UNSIGNED pool_size, + UNSIGNED min_allocation, OPTION suspend_type); +STATUS NU_Delete_Memory_Pool(NU_MEMORY_POOL *pool); + +STATUS NU_Allocate_Memory(NU_MEMORY_POOL *pool, VOID **return_pointer, + UNSIGNED size, UNSIGNED suspend); + +/* The following conditional routes memory allocation calls to functions + that help track memory leaks. */ +#ifdef NU_DEBUG_MEMORY +#define NU_Allocate_Memory(a,b,c,d) ERC_Allocate_Memory(a,b,c,d,__LINE__,__FILE__) +#else +#define NU_Allocate_Memory DMCE_Allocate_Memory +#endif /* NU_DEBUG_MEMORY */ + +STATUS NU_Deallocate_Memory(VOID *memory); +UNSIGNED NU_Established_Memory_Pools(VOID); +STATUS NU_Memory_Pool_Information(NU_MEMORY_POOL *pool, CHAR *name, + VOID **start_address, UNSIGNED *pool_size, + UNSIGNED *min_allocation, UNSIGNED *available, + OPTION *suspend_type, UNSIGNED *tasks_waiting, + NU_TASK **first_task); +UNSIGNED NU_Memory_Pool_Pointers(NU_MEMORY_POOL **pointer_list, + UNSIGNED maximum_pointers); + +/* Define Interrupt management functions. */ + +INT NU_Control_Interrupts(INT new_level); +INT NU_Local_Control_Interrupts(INT new_level); +VOID NU_Restore_Interrupts(VOID); +VOID *NU_Setup_Vector(INT vector, VOID *new_vector); +STATUS NU_Register_LISR(INT vector, + VOID (*new_lisr)(INT), + VOID (**old_lisr)(INT)); +STATUS NU_Activate_HISR(NU_HISR *hisr); +STATUS NU_Create_HISR(NU_HISR *hisr, CHAR *name, + VOID (*hisr_entry)(VOID), OPTION priority, + VOID *stack_address, UNSIGNED stack_size); +STATUS NU_Delete_HISR(NU_HISR *hisr); +NU_HISR *NU_Current_HISR_Pointer(VOID); +UNSIGNED NU_Established_HISRs(VOID); +STATUS NU_HISR_Information(NU_HISR *hisr, CHAR *name, + UNSIGNED *scheduled_count, DATA_ELEMENT *priority, + VOID **stack_base, UNSIGNED *stack_size, + UNSIGNED *minimum_stack); +UNSIGNED NU_HISR_Pointers(NU_HISR **pointer_list, + UNSIGNED maximum_pointers); +VOID NU_Protect(NU_PROTECT *protect_struct); +VOID NU_Unprotect(VOID); + +/* Timer management functions. */ + +STATUS NU_Create_Timer(NU_TIMER *timer, CHAR *name, + VOID (*expiration_routine)(UNSIGNED), UNSIGNED id, + UNSIGNED initial_time, UNSIGNED reschedule_time, + OPTION enable); +STATUS NU_Delete_Timer(NU_TIMER *timer); +STATUS NU_Reset_Timer(NU_TIMER *timer, + VOID (*expiration_routine)(UNSIGNED), + UNSIGNED initial_time, UNSIGNED reschedule_timer, + OPTION enable); +STATUS NU_Control_Timer(NU_TIMER *timer, OPTION enable); +UNSIGNED NU_Established_Timers(VOID); +STATUS NU_Timer_Information(NU_TIMER *timer, CHAR *name, + OPTION *enable, UNSIGNED *expirations, UNSIGNED *id, + UNSIGNED *initial_time, UNSIGNED *reschedule_time); +UNSIGNED NU_Timer_Pointers(NU_TIMER **pointer_list, + UNSIGNED maximum_pointers); +VOID NU_Set_Clock(UNSIGNED new_value); +UNSIGNED NU_Retrieve_Clock(VOID); + +/* Development support functions. */ + +CHAR *NU_Release_Information(VOID); +CHAR *NU_License_Information(VOID); +VOID NU_Disable_History_Saving(VOID); +VOID NU_Enable_History_Saving(VOID); +VOID NU_Make_History_Entry(UNSIGNED param1, UNSIGNED param2, + UNSIGNED param3); +STATUS NU_Retrieve_History_Entry(DATA_ELEMENT *id, + UNSIGNED *param1, UNSIGNED *param2, UNSIGNED *param3, + UNSIGNED *time, NU_TASK **task, NU_HISR **hisr); + +/* Input/Output Driver functions. */ + +STATUS NU_Create_Driver(NU_DRIVER *driver, CHAR *name, + VOID (*driver_entry)(NU_DRIVER *, NU_DRIVER_REQUEST *)); +STATUS NU_Delete_Driver(NU_DRIVER *driver); +STATUS NU_Request_Driver(NU_DRIVER *driver, + NU_DRIVER_REQUEST *request); +STATUS NU_Resume_Driver(NU_TASK *task); +STATUS NU_Suspend_Driver(VOID (*terminate_routine)(VOID *), + VOID *information, UNSIGNED timeout); +UNSIGNED NU_Established_Drivers(VOID); +UNSIGNED NU_Driver_Pointers(NU_DRIVER **pointer_list, + UNSIGNED maximum_pointers); + +#endif + +/* Define Supervisor and User mode functions */ +#if (!defined(NU_SUPERV_USER_MODE)) || (NU_SUPERV_USER_MODE < 1) + +#define NU_IS_SUPERVISOR_MODE() (NU_TRUE) +#define NU_SUPERVISOR_MODE() ((void) 0) +#define NU_USER_MODE() ((void) 0) +#define NU_SUPERV_USER_VARIABLES /* Not a Supervisor/User kernel */ + +#else /* NU_SUPERV_USER_MODE defined */ + +#include "tc_defs.h" +#include "mmu/inc/su_extr.h" + +#endif /* NU_SUPERV_USER_MODE */ + +#ifdef __cplusplus +} /* End of C declarations */ +#endif + +#endif /* !NUCLEUS */ + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/pi_defs.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,126 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* pi_defs.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* PI - Pipe Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains data structure definitions and constants for */ +/* the message Pipe component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* PI_PCB Pipe control block */ +/* PI_SUSPEND Pipe suspension block */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_defs.h Common service definitions */ +/* tc_defs.h Thread Control definitions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* removed protection structure, */ +/* put padding into structure, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "cs_defs.h" /* Common service constants */ +#include "tc_defs.h" /* Thread control constants */ + + +/* Check to see if the file has been included already. */ + +#ifndef PI_DEFS +#define PI_DEFS + + +/* Define constants local to this component. */ + +#define PI_PIPE_ID 0x50495045UL + + +/* Define the Pipe Control Block data type. */ + +typedef struct PI_PCB_STRUCT +{ + CS_NODE pi_created; /* Node for linking to */ + /* created pipe list */ + UNSIGNED pi_id; /* Internal PCB ID */ + CHAR pi_name[NU_MAX_NAME]; /* Pipe name */ + BOOLEAN pi_fixed_size; /* Fixed-size messages? */ + BOOLEAN pi_fifo_suspend; /* Suspension type flag */ +#if PAD_2 + DATA_ELEMENT pi_padding[PAD_2]; +#endif + UNSIGNED pi_pipe_size; /* Total size of pipe */ + UNSIGNED pi_messages; /* Messages in pipe */ + UNSIGNED pi_message_size; /* Size of each message */ + UNSIGNED pi_available; /* Available bytes */ + BYTE_PTR pi_start; /* Start of pipe area */ + BYTE_PTR pi_end; /* End of pipe area + 1 */ + BYTE_PTR pi_read; /* Read pointer */ + BYTE_PTR pi_write; /* Write pointer */ + UNSIGNED pi_tasks_waiting; /* Number of waiting tasks*/ + struct PI_SUSPEND_STRUCT + *pi_urgent_list; /* Urgent message suspend */ + struct PI_SUSPEND_STRUCT + *pi_suspension_list; /* Suspension list */ +} PI_PCB; + + +/* Define the Pipe suspension structure. This structure is allocated off of + the caller's stack. */ + +typedef struct PI_SUSPEND_STRUCT +{ + CS_NODE pi_suspend_link; /* Link to suspend blocks */ + PI_PCB *pi_pipe; /* Pointer to the pipe */ + TC_TCB *pi_suspended_task; /* Task suspended */ + BYTE_PTR pi_message_area; /* Pointer to message area*/ + UNSIGNED pi_message_size; /* Message size requested */ + UNSIGNED pi_actual_size; /* Actual size of message */ + STATUS pi_return_status; /* Return status */ +} PI_SUSPEND; + +#endif + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/pi_extr.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,135 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* pi_extr.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* PI - Pipe Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains function prototypes of all functions */ +/* accessible to other components. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* pi_defs.h Pipe Management constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* modified function prototypes, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "pi_defs.h" /* Include Pipe constants */ + + +/* Check to see if the file has been included already. */ + +#ifndef PI_EXTR +#define PI_EXTR + + +/* Initialization functions. */ + +VOID PII_Initialize(VOID); + + +/* Error checking core functions. */ + +STATUS PICE_Create_Pipe(NU_PIPE *pipe_ptr, CHAR *name, + VOID *start_address, UNSIGNED pipe_size, + OPTION message_type, UNSIGNED message_size, + OPTION suspend_type); +STATUS PICE_Delete_Pipe(NU_PIPE *pipe_ptr); +STATUS PICE_Send_To_Pipe(NU_PIPE *pipe_ptr, VOID *message, + UNSIGNED size, UNSIGNED suspend); +STATUS PICE_Receive_From_Pipe(NU_PIPE *pipe_ptr, VOID *message, + UNSIGNED size, UNSIGNED *actual_size, UNSIGNED suspend); + + +/* Error checking supplemental functions. */ + +STATUS PISE_Reset_Pipe(NU_PIPE *pipe_ptr); +STATUS PISE_Send_To_Front_Of_Pipe(NU_PIPE *pipe_ptr, VOID *message, + UNSIGNED size, UNSIGNED suspend); +STATUS PISE_Broadcast_To_Pipe(NU_PIPE *pipe_ptr, VOID *message, + UNSIGNED size, UNSIGNED suspend); + + +/* Core processing functions. */ + +STATUS PIC_Create_Pipe(NU_PIPE *pipe_ptr, CHAR *name, + VOID *start_address, UNSIGNED pipe_size, + OPTION message_type, UNSIGNED message_size, + OPTION suspend_type); +STATUS PIC_Delete_Pipe(NU_PIPE *pipe_ptr); +STATUS PIC_Send_To_Pipe(NU_PIPE *pipe_ptr, VOID *message, + UNSIGNED size, UNSIGNED suspend); +STATUS PIC_Receive_From_Pipe(NU_PIPE *pipe_ptr, VOID *message, + UNSIGNED size, UNSIGNED *actual_size, UNSIGNED suspend); + + +/* Supplemental processing functions. */ + +STATUS PIS_Reset_Pipe(NU_PIPE *pipe_ptr); +STATUS PIS_Send_To_Front_Of_Pipe(NU_PIPE *pipe_ptr, VOID *message, + UNSIGNED size, UNSIGNED suspend); +STATUS PIS_Broadcast_To_Pipe(NU_PIPE *pipe_ptr, VOID *message, + UNSIGNED size, UNSIGNED suspend); + + +/* Information retrieval functions. */ + +UNSIGNED PIF_Established_Pipes(VOID); +STATUS PIF_Pipe_Information(NU_PIPE *pipe_ptr, CHAR *name, + VOID **start_address, UNSIGNED *pipe_size, + UNSIGNED *available, UNSIGNED *messages, + OPTION *message_type, UNSIGNED *message_size, + OPTION *suspend_type, UNSIGNED *tasks_waiting, + NU_TASK **first_task); +UNSIGNED PIF_Pipe_Pointers(NU_PIPE **pointer_list, + UNSIGNED maximum_pointers); + +#endif + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/pic.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,1617 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* pic.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* PI - Pipe Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the core routines for the pipe management */ +/* component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* PIC_Create_Pipe Create a message pipe */ +/* PIC_Delete_Pipe Delete a message pipe */ +/* PIC_Send_To_Pipe Send message to a pipe */ +/* PIC_Receive_From_Pipe Receive a message from pipe */ +/* PIC_Cleanup Cleanup on timeout or a */ +/* terminate condition */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* pi_extr.h Pipe functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected pointer retrieval */ +/* loop, resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Moved non-core functions into */ +/* supplemental files, changed */ +/* function interfaces to match */ +/* those in prototype, added */ +/* register options, changed */ +/* protection logic to reduce */ +/* overhead, corrected bug in */ +/* pipe reset, optimized item */ +/* copy loops, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "pi_extr.h" /* Pipe functions */ +#include "hi_extr.h" /* History functions */ +#include "profiler.h" /* ProView interface */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *PID_Created_Pipes_List; +extern UNSIGNED PID_Total_Pipes; +extern TC_PROTECT PID_List_Protect; + + +/* Define internal component function prototypes. */ + +VOID PIC_Cleanup(VOID *information); + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PIC_Create_Pipe */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function creates a pipe and then places it on the list */ +/* of created pipes. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* PICE_Create_Pipe Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Add to node to linked-list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Data structure protect */ +/* TCT_Unprotect Un-protect data structure */ +/* */ +/* INPUTS */ +/* */ +/* pipe_ptr Pipe control block pointer */ +/* name Pipe name */ +/* start_address Starting address of actual */ +/* pipe area */ +/* pipe_size Total size of pipe in bytes */ +/* message_type Type of message supported by */ +/* the pipe (fixed/variable) */ +/* message_size Size of message. Variable */ +/* message-length pipes, this */ +/* represents the maximum size*/ +/* suspend_type Suspension type */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS PIC_Create_Pipe(NU_PIPE *pipe_ptr, CHAR *name, + VOID *start_address, UNSIGNED pipe_size, + OPTION message_type, UNSIGNED message_size, + OPTION suspend_type) +{ + +R1 PI_PCB *pipe; /* Pipe control block ptr */ +INT i; /* Working index variable */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input pipe pointer into internal pointer. */ + pipe = (PI_PCB *) pipe_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_CREATE_PIPE_ID, (UNSIGNED) pipe, + (UNSIGNED) name, (UNSIGNED) start_address); + +#endif + + /* First, clear the pipe ID just in case it is an old pipe + Control Block. */ + pipe -> pi_id = 0; + + /* Fill in the pipe name. */ + for (i = 0; i < NU_MAX_NAME; i++) + pipe -> pi_name[i] = name[i]; + + /* Setup the pipe suspension type. */ + if (suspend_type == NU_FIFO) + + /* FIFO suspension is selected, setup the flag accordingly. */ + pipe -> pi_fifo_suspend = NU_TRUE; + + else + + /* Priority suspension is selected. */ + pipe -> pi_fifo_suspend = NU_FALSE; + + /* Setup the pipe message type. */ + if (message_type == NU_FIXED_SIZE) + + /* Fixed-size messages are required. */ + pipe -> pi_fixed_size = NU_TRUE; + else + + /* Variable-size messages are required. */ + pipe -> pi_fixed_size = NU_FALSE; + + /* Setup the message size. */ + pipe -> pi_message_size = message_size; + + /* Clear the messages counter. */ + pipe -> pi_messages = 0; + + /* Setup the actual pipe pointers. */ + pipe -> pi_pipe_size = pipe_size; + + /* Determine if the pipe's size needs to be adjusted. */ + if (pipe -> pi_fixed_size) + + /* The size of a fixed-size message pipe must be an even multiple of + the actual message size. */ + pipe_size = (pipe_size/message_size) * message_size; + + else + + /* Insure that the size is in terms of UNSIGNED data elements. This + insures that the UNSIGNED word is never written past the end of + the pipe. */ + pipe_size = (pipe_size/sizeof(UNSIGNED)) * sizeof(UNSIGNED); + + pipe -> pi_available = pipe_size; + pipe -> pi_start = (BYTE_PTR) start_address; + pipe -> pi_end = pipe -> pi_start + pipe_size; + pipe -> pi_read = (BYTE_PTR) start_address; + pipe -> pi_write = (BYTE_PTR) start_address; + + /* Clear the suspension list pointer. */ + pipe -> pi_suspension_list = NU_NULL; + + /* Clear the number of tasks waiting on the pipe counter. */ + pipe -> pi_tasks_waiting = 0; + + /* Clear the urgent message list pointer. */ + pipe -> pi_urgent_list = NU_NULL; + + /* Initialize link pointers. */ + pipe -> pi_created.cs_previous = NU_NULL; + pipe -> pi_created.cs_next = NU_NULL; + + /* Protect against access to the list of created pipes. */ + TCT_Protect(&PID_List_Protect); + + /* At this point the pipe is completely built. The ID can now be + set and it can be linked into the created pipe list. */ + pipe -> pi_id = PI_PIPE_ID; + + /* Link the pipe into the list of created pipes and increment the + total number of pipes in the system. */ + CSC_Place_On_List(&PID_Created_Pipes_List, &(pipe -> pi_created)); + PID_Total_Pipes++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPipe(RT_PROF_CREATE_PIPE,pipe,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + + /* Release protection against access to the list of created pipes. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PIC_Delete_Pipe */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function deletes a pipe and removes it from the list of */ +/* created pipes. All tasks suspended on the pipe are */ +/* resumed. Note that this function does not free the memory */ +/* associated with the pipe. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* PICE_Delete_Pipe Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove node from list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Protect Protect created list */ +/* TCT_Set_Current_Protect Modify current protection */ +/* TCT_System_Protect Protect against system access*/ +/* TCT_System_Unprotect Release system protection */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* pipe_ptr Pipe control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS PIC_Delete_Pipe(NU_PIPE *pipe_ptr) +{ + +R1 PI_PCB *pipe; /* Pipe control block ptr */ +PI_SUSPEND *suspend_ptr; /* Suspend block pointer */ +PI_SUSPEND *next_ptr; /* Next suspension block ptr */ +STATUS preempt; /* Status for resume call */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input pipe pointer into internal pointer. */ + pipe = (PI_PCB *) pipe_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_DELETE_PIPE_ID, (UNSIGNED) pipe, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Protect against access to the pipe. */ + TCT_System_Protect(); + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPipe(RT_PROF_DELETE_PIPE,pipe,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + + /* Clear the pipe ID. */ + pipe -> pi_id = 0; + + /* Release protection. */ + TCT_Unprotect(); + + /* Protect against access to the list of created pipes. */ + TCT_Protect(&PID_List_Protect); + + /* Remove the pipe from the list of created pipes. */ + CSC_Remove_From_List(&PID_Created_Pipes_List, &(pipe -> pi_created)); + + /* Decrement the total number of created pipes. */ + PID_Total_Pipes--; + + /* Pickup the suspended task pointer list. */ + suspend_ptr = pipe -> pi_suspension_list; + + /* Walk the chain task(s) currently suspended on the pipe. */ + preempt = 0; + while (suspend_ptr) + { + + /* Protect against system access. */ + TCT_System_Protect(); + + /* Resume the suspended task. Insure that the status returned is + NU_PIPE_DELETED. */ + suspend_ptr -> pi_return_status = NU_PIPE_DELETED; + + /* Point to the next suspend structure in the link. */ + next_ptr = (PI_SUSPEND *) (suspend_ptr -> pi_suspend_link.cs_next); + + /* Resume the specified task. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> pi_suspended_task, + NU_PIPE_SUSPEND); + + /* Determine if the next is the same as the head pointer. */ + if (next_ptr == pipe -> pi_suspension_list) + + /* Clear the suspension pointer to signal the end of the list + traversal. */ + suspend_ptr = NU_NULL; + else + + /* Setup the next suspension pointer. */ + suspend_ptr = next_ptr; + + /* Modify current protection. */ + TCT_Set_Current_Protect(&PID_List_Protect); + + /* Clear the system protection. */ + TCT_System_Unprotect(); + } + + /* Pickup the urgent message suspension list. */ + suspend_ptr = pipe -> pi_urgent_list; + + /* Walk the chain task(s) currently suspended on the pipe. */ + while (suspend_ptr) + { + + /* Protect against system access. */ + TCT_System_Protect(); + + /* Resume the suspended task. Insure that the status returned is + NU_PIPE_DELETED. */ + suspend_ptr -> pi_return_status = NU_PIPE_DELETED; + + /* Point to the next suspend structure in the link. */ + next_ptr = (PI_SUSPEND *) (suspend_ptr -> pi_suspend_link.cs_next); + + /* Resume the specified task. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> pi_suspended_task, + NU_PIPE_SUSPEND); + + /* Determine if the next is the same as the head pointer. */ + if (next_ptr == pipe -> pi_urgent_list) + + /* Clear the suspension pointer to signal the end of the list + traversal. */ + suspend_ptr = NU_NULL; + else + + /* Position suspend pointer to the next block. */ + suspend_ptr = next_ptr; + + /* Modify current protection. */ + TCT_Set_Current_Protect(&PID_List_Protect); + + /* Clear the system protection. */ + TCT_System_Unprotect(); + } + + /* Determine if preemption needs to occur. */ + if (preempt) + + /* Transfer control to system to facilitate preemption. */ + TCT_Control_To_System(); + + /* Release protection against access to the list of created pipes. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return a successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PIC_Send_To_Pipe */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sends a message to the specified pipe. The */ +/* message length is determined by the caller. If there are one */ +/* or more tasks suspended on the pipe for a message, the message */ +/* is copied into the message area of the first waiting task. If */ +/* the task's request is satisfied, it is resumed. Otherwise, if */ +/* the pipe cannot hold the message, suspension of the calling */ +/* task is an option of the caller. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* PICE_Send_To_Pipe Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Place on suspend list */ +/* CSC_Priority_Place_On_List Place on priority list */ +/* CSC_Remove_From_List Remove from suspend list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* TCC_Suspend_Task Suspend calling task */ +/* TCC_Task_Priority Pickup task's priority */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Current_Thread Pickup current thread pointer*/ +/* TCT_System_Protect Protect pipe */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* pipe_ptr Pipe control block pointer */ +/* message Pointer to message to send */ +/* size Size of message to send */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If service is successful */ +/* NU_PIPE_FULL If pipe is currently full */ +/* NU_TIMEOUT If timeout on service expires*/ +/* NU_PIPE_DELETED If pipe was deleted during */ +/* suspension */ +/* NU_PIPE_RESET If pipe was reset during */ +/* suspension */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, optimized copy loop, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS PIC_Send_To_Pipe(NU_PIPE *pipe_ptr, VOID *message, UNSIGNED size, + UNSIGNED suspend) +{ + +R1 PI_PCB *pipe; /* Pipe control block ptr */ +PI_SUSPEND suspend_block; /* Allocate suspension block */ +PI_SUSPEND *suspend_ptr; /* Pointer to suspend block */ +R2 BYTE_PTR source; /* Pointer to source */ +R3 BYTE_PTR destination; /* Pointer to destination */ +UNSIGNED copy_size; /* Partial copy size */ +R4 INT i; /* Working counter */ +UNSIGNED pad = 0; /* Number of pad bytes */ +TC_TCB *task; /* Task pointer */ +STATUS preempt; /* Preempt flag */ +STATUS status; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input pipe pointer into internal pointer. */ + pipe = (PI_PCB *) pipe_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_SEND_TO_PIPE_ID, (UNSIGNED) pipe, + (UNSIGNED) message, (UNSIGNED) size); + +#endif + + /* Initialize the status as successful. */ + status = NU_SUCCESS; + + /* Protect against simultaneous access to the pipe. */ + TCT_System_Protect(); + + /* Determine if an extra word of overhead needs to be added to the + calculation. */ + if (pipe -> pi_fixed_size) + + /* No overhead. */ + i = 0; + else + { + + /* Variable messages have one additional word of overhead. */ + i = sizeof(UNSIGNED); + + /* Calculate the number of pad bytes necessary to make keep the pipe + write pointer on an UNSIGNED data element alignment. */ + pad = (((size + sizeof(UNSIGNED) - 1)/sizeof(UNSIGNED)) * + sizeof(UNSIGNED)) - size; + + /* Insure that padding is included in the overhead. */ + i = i + ((INT) pad); + + /* Make special check to see if a suspension needs to be + forced for a variable length message. */ + if ((pipe -> pi_suspension_list) && (pipe -> pi_messages)) + { + + /* Pickup task control block pointer. */ + task = (TC_TCB *) TCT_Current_Thread(); + + /* Now we know that there are other task(s) are suspended trying + to send a variable length message. Determine whether or not + a suspension should be forced. */ + if ((pipe -> pi_fifo_suspend) || + (suspend == NU_NO_SUSPEND) || + ((pipe -> pi_suspension_list) -> pi_suspend_link.cs_priority <= + TCC_Task_Priority(task))) + + /* Bump the computed size to avoid placing the new variable + length message ahead of the suspended tasks. */ + i = (INT) pipe -> pi_available; + } + } + + /* Determine if there is enough room in the pipe for the message. */ + if (pipe -> pi_available < (size + i)) + { + + /* pipe does not have room for the message. Determine if + suspension is required. */ + if (suspend) + { + + /* Suspension is requested. */ + + /* Increment the number of tasks waiting. */ + pipe -> pi_tasks_waiting++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPipe(RT_PROF_SEND_TO_PIPE,pipe,RT_PROF_WAIT); +#endif /* INCLUDE_PROVIEW */ + + /* Setup the suspend block and suspend the calling task. */ + suspend_ptr = &suspend_block; + suspend_ptr -> pi_pipe = pipe; + suspend_ptr -> pi_suspend_link.cs_next = NU_NULL; + suspend_ptr -> pi_suspend_link.cs_previous= NU_NULL; + suspend_ptr -> pi_message_area = (BYTE_PTR) message; + suspend_ptr -> pi_message_size = size; + task = (TC_TCB *) TCT_Current_Thread(); + suspend_ptr -> pi_suspended_task = task; + + /* Determine if priority or FIFO suspension is associated with the + pipe. */ + if (pipe -> pi_fifo_suspend) + { + + /* FIFO suspension is required. Link the suspend block into + the list of suspended tasks on this pipe. */ + CSC_Place_On_List((CS_NODE **) &(pipe -> pi_suspension_list), + &(suspend_ptr -> pi_suspend_link)); + } + else + { + + /* Get the priority of the current thread so the suspend block + can be placed in the appropriate place. */ + suspend_ptr -> pi_suspend_link.cs_priority = + TCC_Task_Priority(task); + + CSC_Priority_Place_On_List((CS_NODE **) + &(pipe -> pi_suspension_list), + &(suspend_ptr -> pi_suspend_link)); + } + + /* Finally, suspend the calling task. Note that the suspension call + automatically clears the protection on the pipe. */ + TCC_Suspend_Task((NU_TASK *) task, NU_PIPE_SUSPEND, + PIC_Cleanup, suspend_ptr, suspend); + + /* Pickup the return status. */ + status = suspend_ptr -> pi_return_status; + } + else + { + + /* Return a status of NU_PIPE_FULL because there is no + room in the pipe for the message. */ + status = NU_PIPE_FULL; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPipe(RT_PROF_SEND_TO_PIPE,pipe,RT_PROF_FAIL); +#endif /* INCLUDE_PROVIEW */ + } + + } + else + { + + /* Determine if a task is waiting on an empty pipe. */ + if ((pipe -> pi_suspension_list) && (pipe -> pi_messages == 0)) + { + + /* Task is waiting on pipe for a message. */ + + /* Decrement the number of tasks waiting on pipe. */ + pipe -> pi_tasks_waiting--; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPipe(RT_PROF_SEND_TO_PIPE,pipe,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + + /* Remove the first suspended block from the list. */ + suspend_ptr = pipe -> pi_suspension_list; + CSC_Remove_From_List((CS_NODE **) &(pipe -> pi_suspension_list), + &(suspend_ptr -> pi_suspend_link)); + + /* Setup the source and destination pointers. */ + source = (BYTE_PTR) message; + destination = suspend_ptr -> pi_message_area; + + /* Initialize the return status. */ + suspend_ptr -> pi_return_status = NU_SUCCESS; + + /* Loop to actually copy the message. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while(1); + + /* Return the size of the message copied. */ + suspend_ptr -> pi_actual_size = size; + + /* Wakeup the waiting task and check for preemption. */ + preempt = + TCC_Resume_Task((NU_TASK *) suspend_ptr -> pi_suspended_task, + NU_PIPE_SUSPEND); + + /* Determine if preemption needs to take place. */ + if (preempt) + + /* Transfer control to the system if the resumed task function + detects a preemption condition. */ + TCT_Control_To_System(); + } + else + { + + /* There is enough room in the pipe and no task is waiting. */ + + /* Setup the source pointer. */ + source = (BYTE_PTR) message; + destination = pipe -> pi_write; + + /* Process according to the type of message supported. */ + if (pipe -> pi_fixed_size) + { + + /* Fixed-size messages are supported by this pipe. */ + + /* Loop to copy the message into the pipe area. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + else + { + + /* Variable-size messages are supported. Processing must + check for pipe wrap-around conditions. */ + + /* Place message size in first location. */ + *((UNSIGNED *) destination) = size; + destination = destination + sizeof(UNSIGNED); + + /* Check for a wrap-around condition on the pipe. */ + if (destination >= pipe -> pi_end) + + /* Wrap the write pointer back to the top of the pipe + area. */ + destination = pipe -> pi_start; + + /* Decrement the number of bytes remaining for this + extra word of overhead. */ + pipe -> pi_available = pipe -> pi_available - + sizeof(UNSIGNED); + + /* Calculate the number of bytes remaining from the write + pointer to the bottom of the pipe. */ + copy_size = pipe -> pi_end - destination; + + /* Determine if the message needs to be wrapped around the + edge of the pipe area. */ + if (copy_size >= size) + { + + /* Copy the whole message at once. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + else + { + + /* Copy the first half of the message. */ + i = (INT) copy_size; + do + { + *(destination) = *(source++); + if ((--i) == 0) + break; + destination++; + } while (1); + + /* Copy the second half of the message. */ + destination = pipe -> pi_start; + i = (INT) (size - copy_size); + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + } + + /* Check again for wrap-around condition on the write pointer. */ + if (destination >= pipe -> pi_end) + + /* Move the write pointer to the top of the pipe area. */ + destination = pipe -> pi_start; + + /* Determine if the pipe supports variable-length messages. If + so, pad bytes are needed to keep UNSIGNED alignment. */ + if (pad) + { + + /* Variable-size message. Add pad bytes to the write + pointer. */ + + /* Calculate the number of bytes remaining from the write + pointer to the bottom of the pipe. */ + copy_size = pipe -> pi_end - destination; + + /* If there is not enough room at the bottom of the pipe, the + pad bytes must be wrapped around to the top. */ + if (copy_size <= pad) + + /* Move write pointer to the top of the pipe and make the + necessary adjustment. */ + destination = pipe -> pi_start + (pad - copy_size); + else + + /* There is enough room in the pipe to simply add the + the pad bytes to the write pointer. */ + destination = destination + pad; + + /* Decrement the number of available bytes. */ + pipe -> pi_available = pipe -> pi_available - pad; + } + + /* Update the actual write pointer. */ + pipe -> pi_write = destination; + + /* Decrement the number of available bytes. */ + pipe -> pi_available = pipe -> pi_available - size; + + /* Increment the number of messages in the pipe. */ + pipe -> pi_messages++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPipe(RT_PROF_SEND_TO_PIPE,pipe,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + } + } + + /* Release protection against access to the pipe. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PIC_Receive_From_Pipe */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function receives a message from the specified pipe. The */ +/* size of the message is specified by the caller. If there is a */ +/* message currently in the pipe, the message is removed from the */ +/* pipe and placed in the caller's area. Suspension is possible */ +/* if the request cannot be satisfied. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* PICE_Receive_From_Pipe Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Place on suspend list */ +/* CSC_Remove_From_List Remove from suspend list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* TCC_Suspend_Task Suspend calling task */ +/* TCC_Task_Priority Pickup task's priority */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Current_Thread Pickup current thread pointer*/ +/* TCT_System_Protect Protect pipe */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* pipe_ptr Pipe control block pointer */ +/* message Pointer to message to send */ +/* size Size of the message */ +/* actual_size Size of message received */ +/* suspend Suspension option if empty */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If service is successful */ +/* NU_PIPE_EMPTY If pipe is currently empty */ +/* NU_TIMEOUT If timeout on service expires*/ +/* NU_PIPE_DELETED If pipe was deleted during */ +/* suspension */ +/* NU_PIPE_RESET If pipe was reset during */ +/* suspension */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, optimized copy loop, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS PIC_Receive_From_Pipe(NU_PIPE *pipe_ptr, VOID *message, + UNSIGNED size, UNSIGNED *actual_size, UNSIGNED suspend) +{ + +R1 PI_PCB *pipe; /* Pipe control block ptr */ +PI_SUSPEND suspend_block; /* Allocate suspension block */ +PI_SUSPEND *suspend_ptr; /* Pointer to suspend block */ +R2 BYTE_PTR source; /* Pointer to source */ +R3 BYTE_PTR destination; /* Pointer to destination */ +TC_TCB *task; /* Task pointer */ +UNSIGNED copy_size; /* Number of bytes to copy */ +UNSIGNED pad = 0; /* Number of pad bytes */ +R4 INT i; /* Working counter */ +STATUS preempt; /* Preemption flag */ +STATUS status; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input pipe pointer into internal pointer. */ + pipe = (PI_PCB *) pipe_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_RECEIVE_FROM_PIPE_ID, (UNSIGNED) pipe, + (UNSIGNED) message, (UNSIGNED) size); + +#endif + + /* Initialize the status as successful. */ + status = NU_SUCCESS; + + /* Protect against simultaneous access to the pipe. */ + TCT_System_Protect(); + + /* Determine if an urgent message request is currently suspended. */ + if (pipe -> pi_urgent_list) + { + + /* If so, copy the message from the suspended request block and + resume the associated task. */ + + /* Decrement the number of tasks waiting on pipe. */ + pipe -> pi_tasks_waiting--; + + /* Remove the first suspended block from the list. */ + suspend_ptr = pipe -> pi_urgent_list; + CSC_Remove_From_List((CS_NODE **) &(pipe -> pi_urgent_list), + &(suspend_ptr -> pi_suspend_link)); + + /* Setup the source and destination pointers. */ + destination = (BYTE_PTR) message; + source = suspend_ptr -> pi_message_area; + + /* Initialize the return status. */ + suspend_ptr -> pi_return_status = NU_SUCCESS; + + /* Loop to actually copy the message. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + + /* Return the size of the message copied. */ + *actual_size = suspend_ptr -> pi_message_size; + + /* Wakeup the waiting task and check for preemption. */ + preempt = + TCC_Resume_Task((NU_TASK *) suspend_ptr -> pi_suspended_task, + NU_PIPE_SUSPEND); + + /* Determine if preemption needs to take place. */ + if (preempt) + + /* Transfer control to the system if the resumed task function + detects a preemption condition. */ + TCT_Control_To_System(); + } + + /* Determine if there are messages in the pipe. */ + else if (pipe -> pi_messages) + { + + /* Copy message from pipe into the caller's area. */ + + /* Setup the source and destination pointers. */ + destination = (BYTE_PTR) message; + source = pipe -> pi_read; + + /* Process according to the type of message supported by the pipe. */ + if (pipe -> pi_fixed_size) + { + + /* Pipe supports fixed-size messages. */ + + /* Copy the message from the pipe area into the destination. */ + i = (INT) size; + do + { + *(destination) = *(source++); + if ((--i) == 0) + break; + destination++; + } while (1); + } + else + { + + /* Pipe supports variable-size messages. */ + + /* Variable length message size is actually in the pipe area. */ + size = *((UNSIGNED *) source); + source = source + sizeof(UNSIGNED); + + /* Check for a wrap-around condition on the pipe. */ + if (source >= pipe -> pi_end) + + /* Wrap the read pointer back to the top of the pipe + area. */ + source = pipe -> pi_start; + + /* Increment the number of available bytes in the pipe. */ + pipe -> pi_available = pipe -> pi_available + sizeof(UNSIGNED); + + /* Calculate the number of pad bytes necessary to keep + the pipe read pointer on an UNSIGNED data element alignment.*/ + pad = (((size + sizeof(UNSIGNED) - 1)/sizeof(UNSIGNED)) * + sizeof(UNSIGNED)) - size; + + /* Calculate the number of bytes remaining from the read pointer + to the bottom of the pipe. */ + copy_size = pipe -> pi_end - source; + + /* Determine if the message needs to be wrapped around the + edge of the pipe area. */ + if (copy_size >= size) + { + + /* Copy the whole message at once. */ + i = (INT) size; + do + { + *(destination) = *(source++); + if ((--i) == 0) + break; + destination++; + } while (1); + } + else + { + + /* Copy the first half of the message. */ + i = (INT) copy_size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + + /* Copy the second half of the message. */ + source = pipe -> pi_start; + i = (INT) (size - copy_size); + do + { + *(destination) = *(source++); + if ((--i) == 0) + break; + destination++; + } while (1); + } + } + + /* Check again for wrap-around condition on the read pointer. */ + if (source >= pipe -> pi_end) + + /* Move the read pointer to the top of the pipe area. */ + source = pipe -> pi_start; + + /* Determine if the pipe supports variable-length messages. If + so, pad bytes are needed to keep UNSIGNED alignment. */ + if (pad) + { + + /* Variable-size message. Add pad bytes to the read + pointer. */ + + /* Calculate the number of bytes remaining from the read + pointer to the bottom of the pipe. */ + copy_size = pipe -> pi_end - source; + + /* If there is not enough room at the bottom of the pipe, the + pad bytes must be wrapped around to the top. */ + if (copy_size <= pad) + + /* Move read pointer to the top of the pipe and make the + necessary adjustment. */ + source = pipe -> pi_start + (pad - copy_size); + else + + /* There is enough room in the pipe to simply add the + the pad bytes to the read pointer. */ + source = source + pad; + + /* Add pad bytes to the available bytes count. */ + pipe -> pi_available = pipe -> pi_available + pad; + } + + /* Adjust the actual read pointer. */ + pipe -> pi_read = source; + + /* Increment the number of available bytes. */ + pipe -> pi_available = pipe -> pi_available + size; + + /* Decrement the number of messages in the pipe. */ + pipe -> pi_messages--; + + /* Return the number of bytes received. */ + *actual_size = size; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPipe(RT_PROF_RECEIVE_FROM_PIPE,pipe,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + + /* Determine if any tasks suspended on a full pipe can be woken + up. */ + if (pipe -> pi_suspension_list) + { + + /* Pickup the suspension list and examine suspension blocks + to see if the message could now fit in the pipe. */ + suspend_ptr = pipe -> pi_suspension_list; + preempt = NU_FALSE; + size = suspend_ptr -> pi_message_size; + i = 0; + pad = 0; + + /* Overhead of each pipe message. */ + if (!pipe -> pi_fixed_size) + { + + /* Variable messages have one additional word of overhead. */ + i = sizeof(UNSIGNED); + + /* Calculate the number of pad bytes necessary to keep + the pipe write pointer on an UNSIGNED data element + alignment. */ + pad = (((size + sizeof(UNSIGNED) - 1)/sizeof(UNSIGNED)) * + sizeof(UNSIGNED)) - size; + + /* Insure that padding is included in the overhead. */ + i = i + ((INT) pad); + } + + while ((suspend_ptr) && ((size + i) <= pipe -> pi_available)) + { + + /* Place the suspended task's message into the pipe. */ + + /* Setup the source and destination pointers. */ + source = suspend_ptr -> pi_message_area; + destination = pipe -> pi_write; + + /* Process according to the type of message supported. */ + if (pipe -> pi_fixed_size) + { + + /* Fixed-size messages are supported by this pipe. */ + + /* Loop to copy the message into the pipe area. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + else + { + + /* Variable-size messages are supported. Processing must + check for pipe wrap-around conditions. */ + + /* Place message size in first location. */ + *((UNSIGNED *) destination) = size; + destination = destination + sizeof(UNSIGNED); + + /* Check for a wrap-around condition on the pipe. */ + if (destination >= pipe -> pi_end) + + /* Wrap the write pointer back to the top of the pipe + area. */ + destination = pipe -> pi_start; + + /* Decrement the number of bytes remaining for this + extra word of overhead. */ + pipe -> pi_available = pipe -> pi_available - + sizeof(UNSIGNED); + + /* Calculate the number of bytes remaining from the write + pointer to the bottom of the pipe. */ + copy_size = pipe -> pi_end - destination; + + /* Determine if the message needs to be wrapped around the + edge of the pipe area. */ + if (copy_size >= size) + { + + /* Copy the whole message at once. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + else + { + + /* Copy the first half of the message. */ + i = (INT) copy_size; + do + { + *(destination) = *(source++); + if ((--i) == 0) + break; + destination++; + } while (1); + + /* Copy the second half of the message. */ + destination = pipe -> pi_start; + i = (INT) (size - copy_size); + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + } + + /* Check again for wrap-around condition on the write + pointer. */ + if (destination >= pipe -> pi_end) + + /* Move the write pointer to the top of the pipe area. */ + destination = pipe -> pi_start; + + /* Determine if the pipe supports variable-length messages. If + so, pad bytes are needed to keep UNSIGNED alignment. */ + if (pad) + { + + /* Variable-size message. Add pad bytes to the write + pointer. */ + + /* Calculate the number of bytes remaining from the write + pointer to the bottom of the pipe. */ + copy_size = pipe -> pi_end - destination; + + /* If there is not enough room at the bottom of the pipe, + the pad bytes must be wrapped around to the top. */ + if (copy_size <= pad) + + /* Move write pointer to the top of the pipe and make + the necessary adjustment. */ + destination = pipe -> pi_start + (pad - copy_size); + else + + /* There is enough room in the pipe to simply add + the pad bytes to the write pointer. */ + destination = destination + pad; + + /* Decrement the number of available bytes. */ + pipe -> pi_available = pipe -> pi_available - pad; + } + + /* Update the actual write pointer. */ + pipe -> pi_write = destination; + + /* Decrement the number of available bytes. */ + pipe -> pi_available = pipe -> pi_available - size; + + /* Increment the number of messages in the pipe. */ + pipe -> pi_messages++; + + /* Decrement the number of tasks waiting counter. */ + pipe -> pi_tasks_waiting--; + + /* Remove the first suspended block from the list. */ + CSC_Remove_From_List((CS_NODE **) + &(pipe -> pi_suspension_list), + &(suspend_ptr -> pi_suspend_link)); + + /* Return a successful status. */ + suspend_ptr -> pi_return_status = NU_SUCCESS; + + /* Resume the suspended task. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> pi_suspended_task, + NU_PIPE_SUSPEND); + + /* Setup suspend pointer to the head of the list. */ + suspend_ptr = pipe -> pi_suspension_list; + + /* Determine if there really is another suspended block. If + there is and the pipe supports variable length messages, + calculate new size and padding parameters. */ + if ((suspend_ptr) && (!pipe -> pi_fixed_size)) + { + + /* Get the next message size. */ + size = suspend_ptr -> pi_message_size; + + /* Variable messages have one additional word of + overhead. */ + i = sizeof(UNSIGNED); + + /* Calculate the number of pad bytes necessary to + keep the pipe write pointer on an UNSIGNED data element + alignment. */ + pad = (((size + sizeof(UNSIGNED) - 1)/sizeof(UNSIGNED)) * + sizeof(UNSIGNED)) - size; + + /* Insure that padding is included in the overhead. */ + i = i + ((INT) pad); + } + } + + /* Determine if a preempt condition is present. */ + if (preempt) + + /* Transfer control to the system if the resumed task function + detects a preemption condition. */ + TCT_Control_To_System(); + } + } + else + { + + /* pipe is empty. Determine if the task wants to suspend. */ + if (suspend) + { + + /* Increment the number of tasks waiting on the pipe counter. */ + pipe -> pi_tasks_waiting++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPipe(RT_PROF_RECEIVE_FROM_PIPE,pipe,RT_PROF_WAIT); +#endif /* INCLUDE_PROVIEW */ + + /* Setup the suspend block and suspend the calling task. */ + suspend_ptr = &suspend_block; + suspend_ptr -> pi_pipe = pipe; + suspend_ptr -> pi_suspend_link.cs_next = NU_NULL; + suspend_ptr -> pi_suspend_link.cs_previous = NU_NULL; + suspend_ptr -> pi_message_area = (BYTE_PTR) message; + suspend_ptr -> pi_message_size = size; + task = (TC_TCB *) TCT_Current_Thread(); + suspend_ptr -> pi_suspended_task = task; + + /* Determine if priority or FIFO suspension is associated with the + pipe. */ + if (pipe -> pi_fifo_suspend) + { + + /* FIFO suspension is required. Link the suspend block into + the list of suspended tasks on this pipe. */ + CSC_Place_On_List((CS_NODE **) &(pipe -> pi_suspension_list), + &(suspend_ptr -> pi_suspend_link)); + } + else + { + + /* Get the priority of the current thread so the suspend block + can be placed in the appropriate place. */ + suspend_ptr -> pi_suspend_link.cs_priority = + TCC_Task_Priority(task); + + CSC_Priority_Place_On_List((CS_NODE **) + &(pipe -> pi_suspension_list), + &(suspend_ptr -> pi_suspend_link)); + } + + /* Finally, suspend the calling task. Note that the suspension call + automatically clears the protection on the pipe. */ + TCC_Suspend_Task((NU_TASK *) task, NU_PIPE_SUSPEND, + PIC_Cleanup, suspend_ptr, suspend); + + /* Pickup the status of the request. */ + status = suspend_ptr -> pi_return_status; + *actual_size = suspend_ptr -> pi_actual_size; + } + else + { + + /* Return a status of NU_PIPE_EMPTY because there are no + messages in the pipe. */ + status = NU_PIPE_EMPTY; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPipe(RT_PROF_RECEIVE_FROM_PIPE,pipe,RT_PROF_FAIL); +#endif /* INCLUDE_PROVIEW */ + } + } + + /* Release protection against access to the pipe. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PIC_Cleanup */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for removing a suspension block */ +/* from a pipe. It is not called unless a timeout or a task */ +/* terminate is in progress. Note that protection is already in */ +/* effect - the same protection at suspension time. This routine */ +/* must be called from Supervisor mode in Supervisor/User mode */ +/* switching kernels. */ +/* */ +/* CALLED BY */ +/* */ +/* TCC_Timeout Task timeout */ +/* TCC_Terminate Task terminate */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove suspend block from */ +/* the suspension list */ +/* */ +/* INPUTS */ +/* */ +/* information Pointer to suspend block */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +VOID PIC_Cleanup(VOID *information) +{ + +PI_SUSPEND *suspend_ptr; /* Suspension block pointer */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Use the information pointer as a suspend pointer. */ + suspend_ptr = (PI_SUSPEND *) information; + + /* By default, indicate that the service timed-out. It really does not + matter if this function is called from a terminate request since + the task does not resume. */ + suspend_ptr -> pi_return_status = NU_TIMEOUT; + + /* Decrement the number of tasks waiting counter. */ + (suspend_ptr -> pi_pipe) -> pi_tasks_waiting--; + + /* Determine if the suspend block is one the urgent list. */ + if ((suspend_ptr -> pi_pipe) -> pi_urgent_list) + { + /* Unlink the suspend block from the urgent list. */ + CSC_Remove_From_List((CS_NODE **) + &((suspend_ptr -> pi_pipe) -> pi_urgent_list), + &(suspend_ptr -> pi_suspend_link)); + } + else + { + /* Unlink the suspend block from the suspension list. */ + CSC_Remove_From_List((CS_NODE **) + &((suspend_ptr -> pi_pipe) -> pi_suspension_list), + &(suspend_ptr -> pi_suspend_link)); + } + + /* Return to user mode */ + NU_USER_MODE(); +} + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/pice.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,497 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* pice.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* PI - Pipe Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains error checking routines for core functions */ +/* of the Pipe component. This permits easy removal of error */ +/* checking logic when it is not needed. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* PICE_Create_Pipe Create a pipe */ +/* PICE_Delete_Pipe Delete a pipe */ +/* PICE_Send_To_Pipe Send a pipe message */ +/* PICE_Receive_From_Pipe Receive a pipe message */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* pi_extr.h Pipe functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Split original error checking */ +/* file and changed function */ +/* interfaces, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 12-19-1995 Modified PICE_Receive_From_Pipe, */ +/* resulting in version 1.1+ */ +/* (spr065) */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 06-04-1998 Modified PICE_Send_To_Pipe to */ +/* check for a size of 0, created */ +/* version 1.3a. (SPR493) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "pi_extr.h" /* Pipe functions */ + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PICE_Create_Pipe */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the pipe create function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* PIC_Create_Pipe Actual create pipe function */ +/* */ +/* INPUTS */ +/* */ +/* pipe_ptr Pipe control block pointer */ +/* name Pipe name */ +/* start_address Starting address of actual */ +/* pipe area */ +/* pipe_size Total size of pipe */ +/* message_type Type of message supported by */ +/* the pipe (fixed/variable) */ +/* message_size Size of message. Variable */ +/* message-length queues, this*/ +/* represents the maximum size*/ +/* suspend_type Suspension type */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_PIPE Invalid pipe pointer */ +/* NU_INVALID_MEMORY Invalid pipe starting addr */ +/* NU_INVALID_SIZE Invalid pipe size and/or */ +/* size of message */ +/* NU_INVALID_MESSAGE Invalid message type */ +/* NU_INVALID_SUSPEND Invalid suspend type */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS PICE_Create_Pipe(NU_PIPE *pipe_ptr, CHAR *name, + VOID *start_address, UNSIGNED pipe_size, + OPTION message_type, UNSIGNED message_size, + OPTION suspend_type) +{ + +PI_PCB *pipe; +STATUS status; +UNSIGNED overhead; + + + /* Move input pipe pointer into internal pointer. */ + pipe = (PI_PCB *) pipe_ptr; + + + /* Determine if pipe supports variable length messages. If so, + additional bytes of overhead are required. */ + if (message_type == NU_VARIABLE_SIZE) + + /* Calculate the number of overhead bytes necessary for the additional + word of overhead and the pad-bytes required to keep the pipe + write pointer on an UNSIGNED data element alignment. */ + overhead = sizeof(UNSIGNED) + + (((message_size + sizeof(UNSIGNED) - 1)/sizeof(UNSIGNED)) * + sizeof(UNSIGNED)) - message_size; + + else + + /* Fixed-size message queues require no additional overhead. */ + overhead = 0; + + + /* Determine if there is an error with the pipe pointer. */ + if ((pipe == NU_NULL) || (pipe -> pi_id == PI_PIPE_ID)) + + /* Indicate that the pipe pointer is invalid. */ + status = NU_INVALID_PIPE; + + else if (start_address == NU_NULL) + + /* Indicate that the starting address of the pipe is invalid. */ + status = NU_INVALID_MEMORY; + + else if ((pipe_size == 0) || (message_size == 0) || + ((message_size + overhead) > pipe_size)) + + /* Indicate that one or both of the size parameters are invalid. */ + status = NU_INVALID_SIZE; + + else if ((message_type != NU_FIXED_SIZE) && + (message_type != NU_VARIABLE_SIZE)) + + /* Indicate that the message type is invalid. */ + status = NU_INVALID_MESSAGE; + + else if ((suspend_type != NU_FIFO) && (suspend_type != NU_PRIORITY)) + + /* Indicate that the suspend type is invalid. */ + status = NU_INVALID_SUSPEND; + + else + + /* All the parameters are okay, call the actual function to create + a pipe. */ + status = PIC_Create_Pipe(pipe_ptr, name, start_address, pipe_size, + message_type, message_size, suspend_type); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PICE_Delete_Pipe */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameter supplied */ +/* to the pipe delete function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* PIC_Delete_Pipe Actual delete pipe function */ +/* */ +/* INPUTS */ +/* */ +/* pipe_ptr Pipe control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_PIPE Invalid pipe pointer */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS PICE_Delete_Pipe(NU_PIPE *pipe_ptr) +{ + +PI_PCB *pipe; +STATUS status; + + + /* Move input pipe pointer into internal pointer. */ + pipe = (PI_PCB *) pipe_ptr; + + + /* Determine if there is an error with the pipe pointer. */ + if (pipe == NU_NULL) + + /* Indicate that the pipe pointer is invalid. */ + status = NU_INVALID_PIPE; + + else if (pipe -> pi_id != PI_PIPE_ID) + + /* Indicate that the pipe pointer is invalid. */ + status = NU_INVALID_PIPE; + + else + + /* All the parameters are okay, call the actual function to delete + a pipe. */ + status = PIC_Delete_Pipe(pipe_ptr); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PICE_Send_To_Pipe */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the send message to pipe function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* PIC_Send_To_Pipe Actual send pipe message */ +/* function */ +/* TCCE_Suspend_Error Check suspend validity */ +/* */ +/* INPUTS */ +/* */ +/* pipe_ptr Pipe control block pointer */ +/* message Pointer to message to send */ +/* size Size of message to send */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_PIPE Invalid pipe pointer */ +/* NU_INVALID_POINTER Invalid message pointer */ +/* NU_INVALID_SIZE Invalid message size */ +/* NU_INVALID_SUSPEND Invalid suspend request */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 06-04-1998 Corrected SPR493 */ +/* */ +/*************************************************************************/ +STATUS PICE_Send_To_Pipe(NU_PIPE *pipe_ptr, VOID *message, UNSIGNED size, + UNSIGNED suspend) +{ + +PI_PCB *pipe; +STATUS status; + + + /* Move input pipe pointer into internal pointer. */ + pipe = (PI_PCB *) pipe_ptr; + + /* Determine if there is an error with the pipe pointer. */ + if (pipe == NU_NULL) + + /* Indicate that the pipe pointer is invalid. */ + status = NU_INVALID_PIPE; + + else if (pipe -> pi_id != PI_PIPE_ID) + + /* Indicate that the pipe pointer is invalid. */ + status = NU_INVALID_PIPE; + + else if (message == NU_NULL) + + /* Indicate that the pointer to the message is invalid. */ + status = NU_INVALID_POINTER; + + else if (size == 0) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + else if ((pipe -> pi_fixed_size) && (size != pipe -> pi_message_size)) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + else if ((!pipe -> pi_fixed_size) && (size > pipe -> pi_message_size)) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + else if ((suspend) && (TCCE_Suspend_Error())) + + /* Indicate that suspension is only valid from a non-task thread. */ + status = NU_INVALID_SUSPEND; + + else + + /* All the parameters are okay, call the actual function to send + a message to a pipe. */ + status = PIC_Send_To_Pipe(pipe_ptr, message, size, suspend); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PICE_Receive_From_Pipe */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the receive message from pipe function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* PIC_Receive_From_Pipe Actual receive message from */ +/* pipe */ +/* TCCE_Suspend_Error Check suspend validity */ +/* */ +/* INPUTS */ +/* */ +/* pipe_ptr Pipe control block pointer */ +/* message Pointer to message to send */ +/* size Size of the message */ +/* actual_size Size of message received */ +/* suspend Suspension option if empty */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_PIPE Invalid pipe pointer */ +/* NU_INVALID_POINTER Invalid message pointer */ +/* NU_INVALID_SIZE Invalid message size */ +/* NU_INVALID_SUSPEND Invalid suspend request */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 12-19-1995 Changed the variable pipe check */ +/* from "message size not equal */ +/* to pipe message size" to */ +/* "message size greater than */ +/* pipe message size",resulting */ +/* in version 1.1+ (spr065) */ +/* */ +/*************************************************************************/ +STATUS PICE_Receive_From_Pipe(NU_PIPE *pipe_ptr, VOID *message, + UNSIGNED size, UNSIGNED *actual_size, UNSIGNED suspend) +{ + +PI_PCB *pipe; +STATUS status; + + + /* Move input pipe pointer into internal pointer. */ + pipe = (PI_PCB *) pipe_ptr; + + /* Determine if there is an error with the pipe pointer. */ + if (pipe == NU_NULL) + + /* Indicate that the pipe pointer is invalid. */ + status = NU_INVALID_PIPE; + + else if (pipe -> pi_id != PI_PIPE_ID) + + /* Indicate that the pipe pointer is invalid. */ + status = NU_INVALID_PIPE; + + else if (message == NU_NULL) + + /* Indicate that the pointer to the message is invalid. */ + status = NU_INVALID_POINTER; + + else if (size == 0) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + else if ((pipe -> pi_fixed_size) && (size != pipe -> pi_message_size)) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + else if ((!pipe -> pi_fixed_size) && (size > pipe -> pi_message_size)) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + else if ((suspend) && (TCCE_Suspend_Error())) + + /* Indicate that suspension is only valid from a non-task thread. */ + status = NU_INVALID_SUSPEND; + + else + + /* All the parameters are okay, call the actual function to receive + a message from a pipe. */ + status = PIC_Receive_From_Pipe(pipe_ptr, message, size, actual_size, + suspend); + + /* Return completion status. */ + return(status); +} + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/pid.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,87 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* pid.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* PI - Pipe Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains global data structures for use within the */ +/* pipe management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* PID_Created_Pipe_List Pointer to the linked-list */ +/* of created pipes */ +/* PID_Total_Pipes Total number of created */ +/* pipes */ +/* PID_List_Protect Pipe list protection */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* pi_defs.h Pipe Management constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified copyright, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + +#include "pi_defs.h" /* Pipe constants */ + + +/* PID_Created_Pipes_List is the head pointer of the linked list of + created pipes. If the list is NU_NULL, there are no pipes + created. */ + +CS_NODE *PID_Created_Pipes_List; + + +/* PID_Total_Pipes contains the number of currently created + pipes. */ + +UNSIGNED PID_Total_Pipes; + + +/* PID_List_Protect is a list protection structure used to block any other + thread from access to the created pipe list. */ + +TC_PROTECT PID_List_Protect; + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/pif.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,393 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* pif.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* PI - Pipe Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains routines to obtain facts about the Pipe */ +/* management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* PIF_Established_Pipes Number of created pipes */ +/* PIF_Pipe_Information Retrieve pipe information */ +/* PIF_Pipe_Pointers Build pipe pointer list */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* pi_extr.h Pipe functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Initial version of pipe fact */ +/* service file, version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 11-18-1996 Protected Informational service */ +/* from NULL Control Block pointers */ +/* creating 1.2a. (SPR220) */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "pi_extr.h" /* Pipe functions */ +#include "hi_extr.h" /* History functions */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *PID_Created_Pipes_List; +extern UNSIGNED PID_Total_Pipes; +extern TC_PROTECT PID_List_Protect; + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PIF_Established_Pipes */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the current number of established */ +/* pipes. Pipes previously deleted are no longer considered */ +/* established. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* PID_Total_Pipes Number of established */ +/* pipes */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED PIF_Established_Pipes(VOID) +{ + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Return the number of established pipes. */ + return(PID_Total_Pipes); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PIF_Pipe_Pointers */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function builds a list of pipe pointers, starting at the */ +/* specified location. The number of pipe pointers placed in the */ +/* list is equivalent to the total number of pipes or the maximum */ +/* number of pointers specified in the call. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect created list */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* pointer_list Pointer to the list area */ +/* maximum_pointers Maximum number of pointers */ +/* */ +/* OUTPUTS */ +/* */ +/* pointers Number of pipe pointers */ +/* placed in the list */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected pointer retrieval */ +/* loop, resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED PIF_Pipe_Pointers(NU_PIPE **pointer_list,UNSIGNED maximum_pointers) +{ + +CS_NODE *node_ptr; /* Pointer to each QCB */ +UNSIGNED pointers; /* Number of pointers in list*/ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Initialize the number of pointers returned. */ + pointers = 0; + + /* Protect against access to the list of created pipes. */ + TCT_Protect(&PID_List_Protect); + + /* Loop until all pipe pointers are in the list or until the maximum + list size is reached. */ + node_ptr = PID_Created_Pipes_List; + while ((node_ptr) && (pointers < maximum_pointers)) + { + + /* Place the node into the destination list. */ + *pointer_list++ = (NU_PIPE *) node_ptr; + + /* Increment the pointers variable. */ + pointers++; + + /* Position the node pointer to the next node. */ + node_ptr = node_ptr -> cs_next; + + /* Determine if the pointer is at the head of the list. */ + if (node_ptr == PID_Created_Pipes_List) + + /* The list search is complete. */ + node_ptr = NU_NULL; + } + + /* Release protection against access to the list of created pipes. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the number of pointers in the list. */ + return(pointers); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PIF_Pipe_Information */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns information about the specified pipe. */ +/* However, if the supplied pipe pointer is invalid, the */ +/* function simply returns an error status. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_System_Protect Protect pipe */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* pipe_ptr Pointer to the pipe */ +/* name Destination for the name */ +/* start_address Destination for the start */ +/* address of the pipe */ +/* pipe_size Destination for pipe size */ +/* available Destination for available */ +/* room in pipe */ +/* messages Destination for number of */ +/* messages piped */ +/* message_type Destination for message type */ +/* message_size Destination for message size */ +/* suspend_type Destination for suspension */ +/* type */ +/* tasks_waiting Destination for the tasks */ +/* waiting count */ +/* first_task Destination for the pointer */ +/* to the first task waiting */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If a valid pipe pointer */ +/* is supplied */ +/* NU_INVALID_PIPE If pipe pointer invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 11-18-1996 Corrected SPR220 */ +/* */ +/*************************************************************************/ +STATUS PIF_Pipe_Information(NU_PIPE *pipe_ptr, CHAR *name, + VOID **start_address, UNSIGNED *pipe_size, + UNSIGNED *available, UNSIGNED *messages, + OPTION *message_type, UNSIGNED *message_size, + OPTION *suspend_type, UNSIGNED *tasks_waiting, + NU_TASK **first_task) +{ + +PI_PCB *pipe; /* Pipe control block ptr */ +INT i; /* Working integer variable */ +STATUS completion; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input pipe pointer into internal pointer. */ + pipe = (PI_PCB *) pipe_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Determine if this pipe id is valid. */ + if ((pipe != NU_NULL) && (pipe -> pi_id == PI_PIPE_ID)) + { + + /* Setup protection of the pipe. */ + TCT_System_Protect(); + + /* The pipe pointer is valid. Reflect this in the completion + status and fill in the actual information. */ + completion = NU_SUCCESS; + + /* Copy the pipe's name. */ + for (i = 0; i < NU_MAX_NAME; i++) + *name++ = pipe -> pi_name[i]; + + /* Determine the suspension type. */ + if (pipe -> pi_fifo_suspend) + *suspend_type = NU_FIFO; + else + *suspend_type = NU_PRIORITY; + + /* Determine the message type. */ + if (pipe -> pi_fixed_size) + *message_type = NU_FIXED_SIZE; + else + *message_type = NU_VARIABLE_SIZE; + + /* Get various information about the pipe. */ + *start_address = (VOID *) pipe -> pi_start; + *pipe_size = pipe -> pi_pipe_size; + *available = pipe -> pi_available; + *messages = pipe -> pi_messages; + *message_size = pipe -> pi_message_size; + + /* Retrieve the number of tasks waiting and the pointer to the + first task waiting. */ + *tasks_waiting = pipe -> pi_tasks_waiting; + if (pipe -> pi_suspension_list) + + /* There is a task waiting. */ + *first_task = (NU_TASK *) + (pipe -> pi_suspension_list) -> pi_suspended_task; + else + + /* There are no tasks waiting. */ + *first_task = NU_NULL; + + /* Release protection of the pipe. */ + TCT_Unprotect(); + } + else + + /* Indicate that the pipe pointer is invalid. */ + completion = NU_INVALID_PIPE; + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the appropriate completion status. */ + return(completion); +} + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/pii.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,125 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* pii.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* PI - Pipe Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the initialization routine for the pipe */ +/* management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* PII_Initialize Pipe Management Initialize */ +/* */ +/* DEPENDENCIES */ +/* */ +/* pi_defs.h Pipe component constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified copyright, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "pi_defs.h" /* Pipe constants */ +#include "pi_extr.h" /* Pipe interfaces */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *PID_Created_Pipes_List; +extern UNSIGNED PID_Total_Pipes; +extern TC_PROTECT PID_List_Protect; + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PII_Initialize */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function initializes the data structures that control the */ +/* operation of the Pipe component (PI). There are no pipes */ +/* initially. */ +/* */ +/* CALLED BY */ +/* */ +/* INC_Initialize System initialization */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* PID_Created_Pipes_List List of created pipes */ +/* PID_Total_Pipes Number of created pipes */ +/* PID_List_Protect Protection for pipe list */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +VOID PII_Initialize(VOID) +{ + + /* Initialize the created pipe list to NU_NULL. */ + PID_Created_Pipes_List = NU_NULL; + + /* Initialize the total number of created pipes to 0. */ + PID_Total_Pipes = 0; + + /* Initialize the list protection structure. */ + PID_List_Protect.tc_tcb_pointer = NU_NULL; +} + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/pis.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,1130 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* pis.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* PI - Pipe Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the supplemental routines for the pipe */ +/* management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* PIS_Reset_Pipe Reset a pipe */ +/* PIS_Send_To_Front_Of_Pipe Send message to pipe's front */ +/* PIS_Broadcast_To_Pipe Broadcast a message to pipe */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* pi_extr.h Pipe functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Created initial version 1.1 from */ +/* routines originally in core */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 02-04-1998 Corrected SPR434 resulting in */ +/* version 1.2a. */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "pi_extr.h" /* Pipe functions */ +#include "hi_extr.h" /* History functions */ +#include "profiler.h" /* ProView interface */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *PID_Created_Pipes_List; +extern UNSIGNED PID_Total_Pipes; +extern TC_PROTECT PID_List_Protect; + + +/* Define internal component function prototypes. */ + +VOID PIC_Cleanup(VOID *information); + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PIS_Reset_Pipe */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function resets the specified pipe back to the original */ +/* state. Any messages in the pipe are discarded. Also, any */ +/* tasks currently suspended on the pipe are resumed with the */ +/* reset status. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* PISE_Reset_Pipe Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_System_Protect Protect against system access*/ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* pipe_ptr Pipe control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* NAME DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, fixed read and write */ +/* pointers to both point at the */ +/* start, resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 02-04-1998 Corrected SPR434. */ +/* */ +/*************************************************************************/ +STATUS PIS_Reset_Pipe(NU_PIPE *pipe_ptr) +{ + +R1 PI_PCB *pipe; /* Pipe control block ptr */ +PI_SUSPEND *suspend_ptr; /* Suspend block pointer */ +PI_SUSPEND *next_ptr; /* Next suspend block pointer*/ +STATUS preempt; /* Status for resume call */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input pipe pointer into internal pointer. */ + pipe = (PI_PCB *) pipe_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_RESET_PIPE_ID, (UNSIGNED) pipe, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Protect against access to the pipe. */ + TCT_System_Protect(); + + /* Pickup the suspended task suspension list. */ + suspend_ptr = pipe -> pi_suspension_list; + + /* Walk the chain task(s) currently suspended on the pipe. */ + preempt = 0; + while (suspend_ptr) + { + + /* Resume the suspended task. Insure that the status returned is + NU_PIPE_RESET. */ + suspend_ptr -> pi_return_status = NU_PIPE_RESET; + + /* Point to the next suspend structure in the link. */ + next_ptr = (PI_SUSPEND *) (suspend_ptr -> pi_suspend_link.cs_next); + + /* Resume the specified task. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> pi_suspended_task, + NU_PIPE_SUSPEND); + + /* Determine if the next is the same as the head pointer. */ + if (next_ptr == pipe -> pi_suspension_list) + + /* Clear the suspension pointer to signal the end of the list + traversal. */ + suspend_ptr = NU_NULL; + else + + /* Position the suspend pointer to the next block. */ + suspend_ptr = next_ptr; + } + + /* Pickup the urgent message suspension list. */ + suspend_ptr = pipe -> pi_urgent_list; + + /* Walk the chain task(s) currently suspended on the pipe. */ + while (suspend_ptr) + { + + /* Resume the suspended task. Insure that the status returned is + NU_PIPE_RESET. */ + suspend_ptr -> pi_return_status = NU_PIPE_RESET; + + /* Point to the next suspend structure in the link. */ + next_ptr = (PI_SUSPEND *) (suspend_ptr -> pi_suspend_link.cs_next); + + /* Resume the specified task. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> pi_suspended_task, + NU_PIPE_SUSPEND); + + /* Determine if the next is the same as the head pointer. */ + if (next_ptr == pipe -> pi_urgent_list) + + /* Clear the suspension pointer to signal the end of the list + traversal. */ + suspend_ptr = NU_NULL; + else + + /* Position the suspend pointer to the next active block. */ + suspend_ptr = next_ptr; + } + + /* Initialize various elements of the pipe. */ + pipe -> pi_available = pipe -> pi_end - pipe -> pi_start; + pipe -> pi_messages = 0; + pipe -> pi_read = pipe -> pi_start; + pipe -> pi_write = pipe -> pi_start; + pipe -> pi_tasks_waiting = 0; + pipe -> pi_suspension_list = NU_NULL; + pipe -> pi_urgent_list = NU_NULL; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPipe(RT_PROF_RESET_PIPE,pipe,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + + /* Determine if preemption needs to occur. */ + if (preempt) + + /* Transfer control to system to facilitate preemption. */ + TCT_Control_To_System(); + + /* Release protection against access to the pipe. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return a successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PIS_Send_To_Front_Of_Pipe */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sends a message to the front of the specified */ +/* message pipe. The message length is determined by the caller. */ +/* If there are any tasks suspended on the pipe for a message, the */ +/* message is copied into the message area of the first waiting */ +/* task and that task is resumed. If there is enough room in the */ +/* pipe, the message is copied in front of all other messages. */ +/* If there is not enough room in the pipe, suspension of the */ +/* caller is possible. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* PISE_Send_To_Front_Of_Pipe Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Place on suspend list */ +/* CSC_Remove_From_List Remove from suspend list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* TCC_Suspend_Task Suspend calling task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Current_Thread Pickup current thread pointer*/ +/* TCT_System_Protect Protect pipe */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* pipe_ptr Pipe control block pointer */ +/* message Pointer to message to send */ +/* size Size of message to send */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If service is successful */ +/* NU_PIPE_FULL If pipe is currently full */ +/* NU_TIMEOUT If timeout on service expires*/ +/* NU_PIPE_DELETED If pipe was deleted during */ +/* suspension */ +/* NU_PIPE_RESET If pipe was reset during */ +/* suspension */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, optimized copy loop, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS PIS_Send_To_Front_Of_Pipe(NU_PIPE *pipe_ptr, VOID *message, + UNSIGNED size, UNSIGNED suspend) +{ + +R1 PI_PCB *pipe; /* Pipe control block ptr */ +PI_SUSPEND suspend_block; /* Allocate suspension block */ +PI_SUSPEND *suspend_ptr; /* Pointer to suspend block */ +R2 BYTE_PTR source; /* Pointer to source */ +R3 BYTE_PTR destination; /* Pointer to destination */ +UNSIGNED copy_size; /* Partial copy size */ +R4 INT i; /* Working counter */ +UNSIGNED pad = 0; /* Number of pad bytes */ +TC_TCB *task; /* Task pointer */ +STATUS preempt; /* Preempt flag */ +STATUS status; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input pipe pointer into internal pointer. */ + pipe = (PI_PCB *) pipe_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_SEND_TO_FRONT_OF_PIPE_ID, (UNSIGNED) pipe, + (UNSIGNED) message, (UNSIGNED) size); + +#endif + + /* Initialize the status as successful. */ + status = NU_SUCCESS; + + /* Protect against simultaneous access to the pipe. */ + TCT_System_Protect(); + + /* Determine if an extra word of overhead needs to be added to the + calculation. */ + if (pipe -> pi_fixed_size) + + /* No overhead. */ + i = 0; + else + { + + /* Variable messages have one additional word of overhead. */ + i = sizeof(UNSIGNED); + + /* Calculate the number of pad bytes necessary to keep the pipe + write pointer on an UNSIGNED data element alignment. */ + pad = (((size + sizeof(UNSIGNED) - 1)/sizeof(UNSIGNED)) * + sizeof(UNSIGNED)) - size; + + /* Insure that padding is included in the overhead. */ + i = i + ((INT) pad); + + /* Make special check to see if a suspension needs to be + forced for a variable length message. */ + if ((pipe -> pi_suspension_list) && (pipe -> pi_messages)) + { + + /* Pickup task control block pointer. */ + task = (TC_TCB *) TCT_Current_Thread(); + + /* Now we know that there are other task(s) are suspended trying + to send a variable length message. Determine whether or not + a suspension should be forced. */ + if ((pipe -> pi_fifo_suspend) || + (suspend == NU_NO_SUSPEND) || + ((pipe -> pi_suspension_list) -> pi_suspend_link.cs_priority <= + TCC_Task_Priority(task))) + + /* Bump the computed size to avoid placing the new variable + length message ahead of the suspended tasks. */ + i = (INT) pipe -> pi_available; + } + } + + /* Determine if there is enough room in the pipe for the message. */ + if (pipe -> pi_available < (size + i)) + { + + /* pipe does not have room for the message. Determine if + suspension is required. */ + if (suspend) + { + + /* Suspension is requested. */ + + /* Increment the number of tasks waiting. */ + pipe -> pi_tasks_waiting++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPipe(RT_PROF_SEND_TO_FRONT_OF_PIPE,pipe,RT_PROF_WAIT); +#endif /* INCLUDE_PROVIEW */ + + /* Setup the suspend block and suspend the calling task. */ + suspend_ptr = &suspend_block; + suspend_ptr -> pi_pipe = pipe; + suspend_ptr -> pi_suspend_link.cs_next = NU_NULL; + suspend_ptr -> pi_suspend_link.cs_previous = NU_NULL; + suspend_ptr -> pi_message_area = (BYTE_PTR) message; + suspend_ptr -> pi_message_size = size; + task = (TC_TCB *) TCT_Current_Thread(); + suspend_ptr -> pi_suspended_task = task; + + /* Place the task on the urgent message suspension list. */ + CSC_Place_On_List((CS_NODE **) &(pipe -> pi_urgent_list), + &(suspend_ptr -> pi_suspend_link)); + + /* Move the head pointer of the list to make this suspension the + first in the list. */ + pipe -> pi_urgent_list = (PI_SUSPEND *) + (pipe -> pi_urgent_list) -> pi_suspend_link.cs_previous; + + /* Finally, suspend the calling task. Note that the suspension call + automatically clears the protection on the pipe. */ + TCC_Suspend_Task((NU_TASK *) task, NU_PIPE_SUSPEND, + PIC_Cleanup, suspend_ptr, suspend); + + /* Pickup the return status. */ + status = suspend_ptr -> pi_return_status; + } + else + { + + /* Return a status of NU_PIPE_FULL because there is no + room in the pipe for the message. */ + status = NU_PIPE_FULL; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPipe(RT_PROF_SEND_TO_FRONT_OF_PIPE,pipe,RT_PROF_FAIL); +#endif /* INCLUDE_PROVIEW */ + + } + } + else + { + + /* Determine if a task is waiting on an empty pipe. */ + if ((pipe -> pi_suspension_list) && (pipe -> pi_messages == 0)) + { + + /* Task is waiting on pipe for a message. */ + + /* Decrement the number of tasks waiting on pipe. */ + pipe -> pi_tasks_waiting--; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPipe(RT_PROF_SEND_TO_FRONT_OF_PIPE,pipe,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + + /* Remove the first suspended block from the list. */ + suspend_ptr = pipe -> pi_suspension_list; + CSC_Remove_From_List((CS_NODE **) &(pipe -> pi_suspension_list), + &(suspend_ptr -> pi_suspend_link)); + + /* Setup the source and destination pointers. */ + source = (BYTE_PTR) message; + destination = suspend_ptr -> pi_message_area; + + /* Initialize the return status. */ + suspend_ptr -> pi_return_status = NU_SUCCESS; + + /* Loop to actually copy the message. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + + /* Return the size of the message copied. */ + suspend_ptr -> pi_actual_size = size; + + /* Wakeup the waiting task and check for preemption. */ + preempt = + TCC_Resume_Task((NU_TASK *) suspend_ptr -> pi_suspended_task, + NU_PIPE_SUSPEND); + + /* Determine if preemption needs to take place. */ + if (preempt) + + /* Transfer control to the system if the resumed task function + detects a preemption condition. */ + TCT_Control_To_System(); + } + else + { + + /* There is enough room in the pipe and no task is waiting. */ + + /* Setup the source pointer. */ + source = (BYTE_PTR) message; + destination = pipe -> pi_read; + + /* Process according to the type of message supported. */ + if (pipe -> pi_fixed_size) + { + + /* Fixed-size message pipe. */ + + /* Determine if the read pointer is at the top of the pipe + area. */ + if (destination == pipe -> pi_start) + + /* Prepare to place the message in the lower part of the + pipe area. */ + destination = pipe -> pi_end - size; + else + + /* Backup the length of the message from the current + read pointer. */ + destination = destination - size; + + /* Adjust the actual read pointer before the copy is done. */ + pipe -> pi_read = destination; + + /* Copy the message into the pipe area. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + else + { + + /* Variable-length message pipe. */ + + /* Calculate the number of bytes remaining from the write + pointer to the bottom of the pipe. */ + copy_size = destination - pipe -> pi_start; + + /* Determine if part of the message needs to be placed at the + bottom of the pipe area. */ + if (copy_size < (size + i)) + + /* Compute the starting location for the message. */ + destination = pipe -> pi_end - ((size + i) - copy_size); + else + + /* Compute the starting location for the message. */ + destination = destination - (size + i); + + /* Adjust the actual pipe read pointer also. */ + pipe -> pi_read = destination; + + /* Place message size in first location. */ + *((UNSIGNED *) destination) = size; + destination = destination + sizeof(UNSIGNED); + + /* Check for a wrap-around condition on the pipe. */ + if (destination >= pipe -> pi_end) + + /* Wrap the write pointer back to the top of the pipe + area. */ + destination = pipe -> pi_start; + + /* Decrement the number of bytes remaining for this + extra word of overhead. */ + pipe -> pi_available = pipe -> pi_available - + sizeof(UNSIGNED); + + /* Calculate the number of bytes remaining from the write + pointer to the bottom of the pipe. */ + copy_size = pipe -> pi_end - destination; + + /* Determine if the message needs to be wrapped around the + edge of the pipe area. */ + if (copy_size >= (size + pad)) + { + + /* Copy the whole message at once. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + else + { + + /* Copy the first half of the message. */ + i = (INT) copy_size; + do + { + *(destination) = *(source++); + if ((--i) == 0) + break; + destination++; + } while (1); + + /* Copy the second half of the message. */ + destination = pipe -> pi_start; + + /* Determine if there is anything left to copy. */ + if (size > copy_size) + { + /* Yes, there is something to copy. */ + i = (INT) (size - copy_size); + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + } + /* Decrement the number of available bytes. */ + pipe -> pi_available = pipe -> pi_available - pad; + } + + /* Decrement the number of available bytes. */ + pipe -> pi_available = pipe -> pi_available - size; + + /* Increment the number of messages in the pipe. */ + pipe -> pi_messages++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPipe(RT_PROF_SEND_TO_FRONT_OF_PIPE,pipe,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + + } + } + + /* Release protection against access to the pipe. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PIS_Broadcast_To_Pipe */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sends a message to all tasks waiting for a message */ +/* from the specified pipe. If there are no tasks waiting for a */ +/* message the service performs like a standard send request. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* PISE_Broadcast_To_Pipe Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Place on suspend list */ +/* CSC_Priority_Place_On_List Place on priority list */ +/* CSC_Remove_From_List Remove from suspend list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* TCC_Suspend_Task Suspend calling task */ +/* TCC_Task_Priority Pickup task's priority */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Current_Thread Pickup current thread pointer*/ +/* TCT_System_Protect Protect pipe */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* pipe_ptr Pipe control block pointer */ +/* message Pointer to message to send */ +/* size Size of message to send */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If service is successful */ +/* NU_PIPE_FULL If pipe is currently full */ +/* NU_TIMEOUT If timeout on service expires*/ +/* NU_PIPE_DELETED If pipe was deleted during */ +/* suspension */ +/* NU_PIPE_RESET If pipe was reset during */ +/* suspension */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, optimized copy loop, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS PIS_Broadcast_To_Pipe(NU_PIPE *pipe_ptr, VOID *message, + UNSIGNED size, UNSIGNED suspend) +{ + +R1 PI_PCB *pipe; /* Pipe control block ptr */ +PI_SUSPEND suspend_block; /* Allocate suspension block */ +PI_SUSPEND *suspend_ptr; /* Pointer to suspend block */ +R2 BYTE_PTR source; /* Pointer to source */ +R3 BYTE_PTR destination; /* Pointer to destination */ +UNSIGNED copy_size; /* Partial copy size */ +UNSIGNED pad = 0; /* Number of pad bytes */ +R4 INT i; /* Working counter */ +TC_TCB *task; /* Task pointer */ +STATUS preempt; /* Preempt flag */ +STATUS status; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input pipe pointer into internal pointer. */ + pipe = (PI_PCB *) pipe_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_BROADCAST_TO_PIPE_ID, (UNSIGNED) pipe, + (UNSIGNED) message, (UNSIGNED) size); + +#endif + + /* Initialize the status as successful. */ + status = NU_SUCCESS; + + /* Protect against simultaneous access to the pipe. */ + TCT_System_Protect(); + + /* Determine if an extra word of overhead needs to be added to the + calculation. */ + if (pipe -> pi_fixed_size) + + /* No overhead. */ + i = 0; + else + { + + /* Variable messages have one additional word of overhead. */ + i = sizeof(UNSIGNED); + + /* Calculate the number of pad bytes necessary to keep the pipe + write pointer on an UNSIGNED data element alignment. */ + pad = (((size + sizeof(UNSIGNED) - 1)/sizeof(UNSIGNED)) * + sizeof(UNSIGNED)) - size; + + /* Insure that padding is included in the overhead. */ + i = i + ((INT) pad); + + /* Make special check to see if a suspension needs to be + forced for a variable length message. */ + if ((pipe -> pi_suspension_list) && (pipe -> pi_messages)) + { + + /* Pickup task control block pointer. */ + task = (TC_TCB *) TCT_Current_Thread(); + + /* Now we know that there are other task(s) are suspended trying + to send a variable length message. Determine whether or not + a suspension should be forced. */ + if ((pipe -> pi_fifo_suspend) || + (suspend == NU_NO_SUSPEND) || + ((pipe -> pi_suspension_list) -> pi_suspend_link.cs_priority <= + TCC_Task_Priority(task))) + + /* Bump the computed size to avoid placing the new variable + length message ahead of the suspended tasks. */ + i = (INT) pipe -> pi_available; + } + } + + /* Determine if there is enough room in the pipe for the message. */ + if (pipe -> pi_available < (size + i)) + { + + /* pipe does not have room for the message. Determine if + suspension is required. */ + if (suspend) + { + + /* Suspension is requested. */ + + /* Increment the number of tasks waiting. */ + pipe -> pi_tasks_waiting++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPipe(RT_PROF_BROADCAST_TO_PIPE,pipe,RT_PROF_WAIT); +#endif /* INCLUDE_PROVIEW */ + + /* Setup the suspend block and suspend the calling task. */ + suspend_ptr = &suspend_block; + suspend_ptr -> pi_pipe = pipe; + suspend_ptr -> pi_suspend_link.cs_next = NU_NULL; + suspend_ptr -> pi_suspend_link.cs_previous = NU_NULL; + suspend_ptr -> pi_message_area = (BYTE_PTR) message; + suspend_ptr -> pi_message_size = size; + task = (TC_TCB *) TCT_Current_Thread(); + suspend_ptr -> pi_suspended_task = task; + + /* Determine if priority or FIFO suspension is associated with the + pipe. */ + if (pipe -> pi_fifo_suspend) + { + + /* FIFO suspension is required. Link the suspend block into + the list of suspended tasks on this pipe. */ + CSC_Place_On_List((CS_NODE **) &(pipe -> pi_suspension_list), + &(suspend_ptr -> pi_suspend_link)); + } + else + { + + /* Get the priority of the current thread so the suspend block + can be placed in the appropriate place. */ + suspend_ptr -> pi_suspend_link.cs_priority = + TCC_Task_Priority(task); + + CSC_Priority_Place_On_List((CS_NODE **) + &(pipe -> pi_suspension_list), + &(suspend_ptr -> pi_suspend_link)); + } + + /* Finally, suspend the calling task. Note that the suspension call + automatically clears the protection on the pipe. */ + TCC_Suspend_Task((NU_TASK *) task, NU_PIPE_SUSPEND, + PIC_Cleanup, suspend_ptr, suspend); + + /* Pickup the return status. */ + status = suspend_ptr -> pi_return_status; + } + else + { + + /* Return a status of NU_PIPE_FULL because there is no + room in the pipe for the message. */ + status = NU_PIPE_FULL; + + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPipe(RT_PROF_BROADCAST_TO_PIPE,pipe,RT_PROF_FAIL); +#endif /* INCLUDE_PROVIEW */ + + } + } + else + { + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPipe(RT_PROF_BROADCAST_TO_PIPE,pipe,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + + /* Determine if a task is waiting on an empty pipe. */ + if ((pipe -> pi_suspension_list) && (pipe -> pi_messages == 0)) + { + + /* Yes, one or more tasks are waiting for a message from this + pipe. */ + preempt = 0; + do + { + + /* Decrement the number of tasks waiting on pipe. */ + pipe -> pi_tasks_waiting--; + + /* Remove the first suspended block from the list. */ + suspend_ptr = pipe -> pi_suspension_list; + CSC_Remove_From_List((CS_NODE **) + &(pipe -> pi_suspension_list), + &(suspend_ptr -> pi_suspend_link)); + + /* Setup the source and destination pointers. */ + source = (BYTE_PTR) message; + destination = suspend_ptr -> pi_message_area; + + /* Initialize the return status. */ + suspend_ptr -> pi_return_status = NU_SUCCESS; + + /* Loop to actually copy the message. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + + /* Return the size of the message copied. */ + suspend_ptr -> pi_actual_size = size; + + /* Wakeup the waiting task and check for preemption. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> pi_suspended_task, + NU_PIPE_SUSPEND); + + /* Move the suspend pointer to the next node, which is now + at the head of the list. */ + suspend_ptr = pipe -> pi_suspension_list; + } while (suspend_ptr); + + /* Determine if preemption needs to take place. */ + if (preempt) + + /* Transfer control to the system if the resumed task function + detects a preemption condition. */ + TCT_Control_To_System(); + } + else + { + + /* There is enough room in the pipe and no task is waiting. */ + + /* Setup the source pointer. */ + source = (BYTE_PTR) message; + destination = pipe -> pi_write; + + /* Process according to the type of message supported. */ + if (pipe -> pi_fixed_size) + { + + /* Fixed-size messages are supported by this pipe. */ + + /* Loop to copy the message into the pipe area. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + else + { + + /* Variable-size messages are supported. Processing must + check for pipe wrap-around conditions. */ + + /* Place message size in first location. */ + *((UNSIGNED *) destination) = size; + destination = destination + sizeof(UNSIGNED); + + /* Check for a wrap-around condition on the pipe. */ + if (destination >= pipe -> pi_end) + + /* Wrap the write pointer back to the top of the pipe + area. */ + destination = pipe -> pi_start; + + /* Decrement the number of bytes remaining for this + extra word of overhead. */ + pipe -> pi_available = pipe -> pi_available - + sizeof(UNSIGNED); + + /* Calculate the number of bytes remaining from the write + pointer to the bottom of the pipe. */ + copy_size = pipe -> pi_end - destination; + + /* Determine if the message needs to be wrapped around the + edge of the pipe area. */ + if (copy_size >= size) + { + + /* Copy the whole message at once. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + else + { + + /* Copy the first half of the message. */ + i = (INT) copy_size; + do + { + *(destination) = *(source++); + if ((--i) == 0) + break; + destination++; + } while (1); + + /* Copy the second half of the message. */ + destination = pipe -> pi_start; + i = (INT) (size - copy_size); + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + } + + /* Check again for wrap-around condition on the write pointer. */ + if (destination >= pipe -> pi_end) + + /* Move the write pointer to the top of the pipe area. */ + destination = pipe -> pi_start; + + /* Determine if the pipe supports variable-length messages. If + so, pad bytes are needed to keep UNSIGNED alignment. */ + if (pad) + { + + /* Variable-size message. Add pad bytes to the write + pointer. */ + + /* Calculate the number of bytes remaining from the write + pointer to the bottom of the pipe. */ + copy_size = pipe -> pi_end - destination; + + /* If there is not enough room at the bottom of the pipe, the + pad bytes must be wrapped around to the top. */ + if (copy_size <= pad) + + /* Move write pointer to the top of the pipe and make the + necessary adjustment. */ + destination = pipe -> pi_start + (pad - copy_size); + else + + /* There is enough room in the pipe to simply add the + the pad bytes to the write pointer. */ + destination = destination + pad; + + /* Decrement the number of available bytes. */ + pipe -> pi_available = pipe -> pi_available - pad; + } + + /* Update the actual write pointer. */ + pipe -> pi_write = destination; + + /* Decrement the number of available bytes. */ + pipe -> pi_available = pipe -> pi_available - size; + + /* Increment the number of messages in the pipe. */ + pipe -> pi_messages++; + } + } + + /* Release protection against access to the pipe. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(status); +} + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/pise.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,351 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* pise.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* PI - Pipe Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains error checking routines for supplemental */ +/* functions of the Pipe component. This permits easy removal of */ +/* error checking logic when it is not needed. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* PISE_Reset_Pipe Reset a pipe */ +/* PISE_Send_To_Front_Of_Pipe Send message to pipe's front */ +/* PISE_Broadcast_To_Pipe Broadcast message to pipe */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* pi_extr.h Pipe functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Created initial version 1.1 from */ +/* routines originally in core */ +/* error checking file */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "pi_extr.h" /* Pipe functions */ + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PISE_Reset_Pipe */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameter supplied */ +/* to the pipe reset function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* PIS_Reset_Pipe Actual reset pipe function */ +/* */ +/* INPUTS */ +/* */ +/* pipe_ptr Pipe control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_PIPE Invalid pipe pointer */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS PISE_Reset_Pipe(NU_PIPE *pipe_ptr) +{ + +PI_PCB *pipe; +STATUS status; + + + /* Move input pipe pointer into internal pointer. */ + pipe = (PI_PCB *) pipe_ptr; + + /* Determine if there is an error with the pipe pointer. */ + if (pipe == NU_NULL) + + /* Indicate that the pipe pointer is invalid. */ + status = NU_INVALID_PIPE; + + else if (pipe -> pi_id != PI_PIPE_ID) + + /* Indicate that the pipe pointer is invalid. */ + status = NU_INVALID_PIPE; + + else + + /* All the parameters are okay, call the actual function to reset + a pipe. */ + status = PIS_Reset_Pipe(pipe_ptr); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PISE_Send_To_Front_Of_Pipe */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the send message to front of pipe function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* PIS_Send_To_Front_Of_Pipe Actual send to front of pipe */ +/* function */ +/* TCCE_Suspend_Error Check suspend validity */ +/* */ +/* INPUTS */ +/* */ +/* pipe_ptr Pipe control block pointer */ +/* message Pointer to message to send */ +/* size Size of message to send */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_PIPE Invalid pipe pointer */ +/* NU_INVALID_POINTER Invalid message pointer */ +/* NU_INVALID_SIZE Invalid message size */ +/* NU_INVALID_SUSPEND Invalid suspend request */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS PISE_Send_To_Front_Of_Pipe(NU_PIPE *pipe_ptr, VOID *message, + UNSIGNED size, UNSIGNED suspend) +{ + +PI_PCB *pipe; +STATUS status; + + + /* Move input pipe pointer into internal pointer. */ + pipe = (PI_PCB *) pipe_ptr; + + /* Determine if there is an error with the pipe pointer. */ + if (pipe == NU_NULL) + + /* Indicate that the pipe pointer is invalid. */ + status = NU_INVALID_PIPE; + + else if (pipe -> pi_id != PI_PIPE_ID) + + /* Indicate that the pipe pointer is invalid. */ + status = NU_INVALID_PIPE; + + else if (message == NU_NULL) + + /* Indicate that the pointer to the message is invalid. */ + status = NU_INVALID_POINTER; + + else if (size == 0) + + /* Indicate that the message size is invalid */ + status = NU_INVALID_SIZE; + + else if ((pipe -> pi_fixed_size) && (size != pipe -> pi_message_size)) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + else if ((!pipe -> pi_fixed_size) && (size > pipe -> pi_message_size)) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + else if ((suspend) && (TCCE_Suspend_Error())) + + /* Indicate that suspension is only valid from a non-task thread. */ + status = NU_INVALID_SUSPEND; + + else + + /* All the parameters are okay, call the actual function to send + a message to a pipe. */ + status = PIS_Send_To_Front_Of_Pipe(pipe_ptr, message, size, suspend); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PISE_Broadcast_To_Pipe */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the broadcast message to pipe function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* PIS_Broadcast_To_Pipe Actual broadcast message to */ +/* pipe function */ +/* TCCE_Suspend_Error Check suspend validity */ +/* */ +/* INPUTS */ +/* */ +/* pipe_ptr Pipe control block pointer */ +/* message Pointer to message to send */ +/* size Size of message to send */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_PIPE Invalid pipe pointer */ +/* NU_INVALID_POINTER Invalid message pointer */ +/* NU_INVALID_SIZE Invalid message size */ +/* NU_INVALID_SUSPEND Invalid suspend request */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS PISE_Broadcast_To_Pipe(NU_PIPE *pipe_ptr, VOID *message, + UNSIGNED size, UNSIGNED suspend) +{ + +PI_PCB *pipe; +STATUS status; + + + /* Move input pipe pointer into internal pointer. */ + pipe = (PI_PCB *) pipe_ptr; + + /* Determine if there is an error with the pipe pointer. */ + if (pipe == NU_NULL) + + /* Indicate that the pipe pointer is invalid. */ + status = NU_INVALID_PIPE; + + else if (pipe -> pi_id != PI_PIPE_ID) + + /* Indicate that the pipe pointer is invalid. */ + status = NU_INVALID_PIPE; + + else if (message == NU_NULL) + + /* Indicate that the pointer to the message is invalid. */ + status = NU_INVALID_POINTER; + + else if (size == 0) + + /* Indicate that the message size is invalid */ + status = NU_INVALID_SIZE; + + else if ((pipe -> pi_fixed_size) && (size != pipe -> pi_message_size)) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + else if ((!pipe -> pi_fixed_size) && (size > pipe -> pi_message_size)) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + else if ((suspend) && (TCCE_Suspend_Error())) + + /* Indicate that suspension is only valid from a non-task thread. */ + status = NU_INVALID_SUSPEND; + + else + + /* All the parameters are okay, call the actual function to broadcast + a message to a pipe. */ + status = PIS_Broadcast_To_Pipe(pipe_ptr, message, size, suspend); + + /* Return completion status. */ + return(status); +} + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/pm_defs.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,134 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* pm_defs.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* PM - Partition Memory Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains data structure definitions and constants for */ +/* the Partition Memory component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* PM_PCB Partition Pool control block */ +/* PM_HEADER Header of each partition */ +/* PM_SUSPEND Partition suspension block */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_defs.h Common service definitions */ +/* tc_defs.h Thread Control definitions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* removed protect structure, */ +/* added padding logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "cs_defs.h" /* Common service constants */ +#include "tc_defs.h" /* Thread control constants */ + + +/* Check to see if the file has been included already. */ + +#ifndef PM_DEFS +#define PM_DEFS + + +/* Define constants local to this component. */ + +#define PM_PARTITION_ID 0x50415254UL +#define PM_OVERHEAD ((sizeof(PM_HEADER) + sizeof(UNSIGNED) \ + - 1)/sizeof(UNSIGNED)) * \ + sizeof(UNSIGNED) + + +/* Define the Partition Pool Control Block data type. */ + +typedef struct PM_PCB_STRUCT +{ + CS_NODE pm_created; /* Node for linking to */ + /* created partition list */ + UNSIGNED pm_id; /* Internal PCB ID */ + CHAR pm_name[NU_MAX_NAME]; /* Partition Pool name */ + VOID *pm_start_address; /* Starting pool address */ + UNSIGNED pm_pool_size; /* Size of pool */ + UNSIGNED pm_partition_size; /* Size of each partition */ + UNSIGNED pm_available; /* Available partitions */ + UNSIGNED pm_allocated; /* Allocated partitions */ + struct PM_HEADER_STRUCT + *pm_available_list; /* Available list */ + BOOLEAN pm_fifo_suspend; /* Suspension type flag */ +#if PAD_1 + DATA_ELEMENT pm_padding[PAD_1]; +#endif + UNSIGNED pm_tasks_waiting; /* Number of waiting tasks*/ + struct PM_SUSPEND_STRUCT + *pm_suspension_list; /* Suspension list */ +} PM_PCB; + + +/* Define the header structure that is in front of each memory partition. */ + +typedef struct PM_HEADER_STRUCT +{ + struct PM_HEADER_STRUCT + *pm_next_available; /* Next available memory */ + /* partition */ + PM_PCB *pm_partition_pool; /* Partition pool pointer */ +} PM_HEADER; + + +/* Define the partition suspension structure. This structure is allocated + off of the caller's stack. */ + +typedef struct PM_SUSPEND_STRUCT +{ + CS_NODE pm_suspend_link; /* Link to suspend blocks */ + PM_PCB *pm_partition_pool; /* Pointer to pool */ + TC_TCB *pm_suspended_task; /* Task suspended */ + VOID *pm_return_pointer; /* Return memory address */ + STATUS pm_return_status; /* Return status */ +} PM_SUSPEND; + +#endif + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/pm_extr.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,111 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* pm_extr.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* PM - Partition Memory Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains function prototypes of all functions */ +/* accessible to other components. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* pm_defs.h Partition Management const. */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* modified function prototypes, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "pm_defs.h" /* Include PM constants */ + + +/* Check to see if the file has been included already. */ + +#ifndef PM_EXTR +#define PM_EXTR + + +/* Initialization functions. */ + +VOID PMI_Initialize(VOID); + + +/* Core error checking functions. */ + +STATUS PMCE_Create_Partition_Pool(NU_PARTITION_POOL *pool_ptr, + CHAR *name, VOID *start_address, UNSIGNED pool_size, + UNSIGNED partition_size, OPTION suspend_type); +STATUS PMCE_Delete_Partition_Pool(NU_PARTITION_POOL *pool_ptr); +STATUS PMCE_Allocate_Partition(NU_PARTITION_POOL *pool_ptr, + VOID **return_pointer, UNSIGNED suspend); +STATUS PMCE_Deallocate_Partition(VOID *partition); + + +/* Core processing functions. */ + +STATUS PMC_Create_Partition_Pool(NU_PARTITION_POOL *pool_ptr, + CHAR *name, VOID *start_address, UNSIGNED pool_size, + UNSIGNED partition_size, OPTION suspend_type); +STATUS PMC_Delete_Partition_Pool(NU_PARTITION_POOL *pool_ptr); +STATUS PMC_Allocate_Partition(NU_PARTITION_POOL *pool_ptr, + VOID **return_pointer, UNSIGNED suspend); +STATUS PMC_Deallocate_Partition(VOID *partition); + + +/* Information retrieval functions. */ + +UNSIGNED PMF_Established_Partition_Pools(VOID); +STATUS PMF_Partition_Pool_Information(NU_PARTITION_POOL *pool_ptr, + CHAR *name, VOID **start_address, UNSIGNED *pool_size, + UNSIGNED *partition_size, UNSIGNED *available, + UNSIGNED *allocated, OPTION *suspend_type, + UNSIGNED *tasks_waiting, NU_TASK **first_task); +UNSIGNED PMF_Partition_Pool_Pointers(NU_PARTITION_POOL **pointer_list, + UNSIGNED maximum_pointers); + +#endif + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/pmc.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,889 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* pmc.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* PM - Partition Memory Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the core routines for the Partition Memory */ +/* Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* PMC_Create_Partition_Pool Create a Partition Pool */ +/* PMC_Delete_Partition_Pool Delete a Partition Pool */ +/* PMC_Allocate_Partition Allocate a partition from a */ +/* pool */ +/* PMC_Deallocate_Partition Deallocate a partition from */ +/* a pool */ +/* PMC_Cleanup Cleanup on timeout or a */ +/* terminate condition */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* pm_extr.h Partition functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected pointer retrieval */ +/* loop, resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Moved non-core functions into */ +/* supplemental files, changed */ +/* function interfaces to match */ +/* those in prototype, added */ +/* register options, changed */ +/* protection logic to reduce */ +/* overhead, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "pm_extr.h" /* Partition functions */ +#include "hi_extr.h" /* History functions */ +#include "profiler.h" /* ProView interface */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *PMD_Created_Pools_List; +extern UNSIGNED PMD_Total_Pools; +extern TC_PROTECT PMD_List_Protect; + + +/* Define internal component function prototypes. */ + +VOID PMC_Cleanup(VOID *information); + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PMC_Create_Partition_Pool */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function creates a memory partition pool and then places it */ +/* on the list of created partition pools. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* PMCE_Create_Partition_Pool Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Add node to linked-list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Data structure protect */ +/* TCT_Unprotect Un-protect data structure */ +/* */ +/* INPUTS */ +/* */ +/* pool_ptr Partition pool control block */ +/* pointer */ +/* name Partition pool name */ +/* start_address Starting address of the pool */ +/* pool_size Number of bytes in the pool */ +/* partition_size Number of bytes in each */ +/* partition of the pool */ +/* suspend_type Suspension type */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS PMC_Create_Partition_Pool(NU_PARTITION_POOL *pool_ptr, CHAR *name, + VOID *start_address, UNSIGNED pool_size, + UNSIGNED partition_size, OPTION suspend_type) +{ + +R1 PM_PCB *pool; /* Pool control block ptr */ +INT i; /* Working index variable */ +BYTE_PTR pointer; /* Working byte pointer */ +PM_HEADER *header_ptr; /* Partition block header ptr*/ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input pool pointer into internal pointer. */ + pool = (PM_PCB *) pool_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_CREATE_PARTITION_POOL_ID, (UNSIGNED) pool, + (UNSIGNED) name, (UNSIGNED) start_address); + +#endif + + /* First, clear the partition pool ID just in case it is an old + pool control block. */ + pool -> pm_id = 0; + + /* Fill in the partition pool name. */ + for (i = 0; i < NU_MAX_NAME; i++) + pool -> pm_name[i] = name[i]; + + /* Save the starting address and size parameters in the partition control + block. */ + pool -> pm_start_address = start_address; + pool -> pm_pool_size = pool_size; + pool -> pm_partition_size = partition_size; + + /* Setup the partition pool suspension type. */ + if (suspend_type == NU_FIFO) + + /* FIFO suspension is selected, setup the flag accordingly. */ + pool -> pm_fifo_suspend = NU_TRUE; + else + + /* Priority suspension is selected. */ + pool -> pm_fifo_suspend = NU_FALSE; + + /* Clear the suspension list pointer. */ + pool -> pm_suspension_list = NU_NULL; + + /* Clear the number of tasks waiting on the partition pool. */ + pool -> pm_tasks_waiting = 0; + + /* Initialize link pointers. */ + pool -> pm_created.cs_previous = NU_NULL; + pool -> pm_created.cs_next = NU_NULL; + + /* Initialize the partition parameters. */ + pool -> pm_available = 0; + pool -> pm_allocated = 0; + pool -> pm_available_list = NU_NULL; + + /* Convert the supplied partition size into something that is evenly + divisible by the sizeof an UNSIGNED data element. This insures + UNSIGNED alignment. */ + partition_size = + ((partition_size + sizeof(UNSIGNED) - 1)/sizeof(UNSIGNED)) * + sizeof(UNSIGNED); + + /* Loop to build and link as many partitions as possible from within the + specified memory area. */ + pointer = (BYTE_PTR) start_address; + while (pool_size >= (PM_OVERHEAD + partition_size)) + { + + /* There is room for another partition. */ + + /* Cast the current pointer variable to a header pointer. */ + header_ptr = (PM_HEADER *) pointer; + + /* Now, build a header and link it into the partition pool + available list- at the front. */ + header_ptr -> pm_partition_pool = pool; + header_ptr -> pm_next_available = pool -> pm_available_list; + pool -> pm_available_list = header_ptr; + + /* Increment the number of partitions available in the pool. */ + pool -> pm_available++; + + /* Decrement the number of bytes remaining in the pool. */ + pool_size = pool_size - (PM_OVERHEAD + partition_size); + + /* Increment the working pointer to the next partition position. */ + pointer = pointer + (PM_OVERHEAD + partition_size); + } + + /* Protect against access to the list of created partition pools. */ + TCT_Protect(&PMD_List_Protect); + + /* At this point the partition pool is completely built. The ID can + now be set and it can be linked into the created partition pool list. */ + pool -> pm_id = PM_PARTITION_ID; + + /* Link the partition pool into the list of created partition pools and + increment the total number of pools in the system. */ + CSC_Place_On_List(&PMD_Created_Pools_List, &(pool -> pm_created)); + PMD_Total_Pools++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPartitionPool(RT_PROF_CREATE_PARTITION_POOL,pool,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + /* Release protection against access to the list of created partition + pools. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PMC_Delete_Partition_Pool */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function deletes a memory partition pool and removes it from*/ +/* the list of created partition pools. All tasks suspended on the */ +/* partition pool are resumed with the appropriate error status. */ +/* Note that this function does not free any memory associated with */ +/* either the pool area or the pool control block. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* PMCE_Delete_Partition_Pool Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove node from list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Protect Protect created list */ +/* TCT_Set_Current_Protect Modify current protection */ +/* TCT_System_Protect Setup system protection */ +/* TCT_System_Unprotect Release system protection */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* pool_ptr Partition pool control block */ +/* pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS PMC_Delete_Partition_Pool(NU_PARTITION_POOL *pool_ptr) +{ + +R1 PM_PCB *pool; /* Pool control block ptr */ +PM_SUSPEND *suspend_ptr; /* Suspend block pointer */ +PM_SUSPEND *next_ptr; /* Next suspend block */ +STATUS preempt; /* Status for resume call */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input pool pointer into internal pointer. */ + pool = (PM_PCB *) pool_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_DELETE_PARTITION_POOL_ID, (UNSIGNED) pool, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Protect against simultaneous access to the partition pool. */ + TCT_System_Protect(); + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPartitionPool(RT_PROF_DELETE_PARTITION_POOL,pool,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + + /* Clear the partition pool ID. */ + pool -> pm_id = 0; + + /* Release protection. */ + TCT_Unprotect(); + + /* Protect against access to the list of created partition pools. */ + TCT_Protect(&PMD_List_Protect); + + /* Remove the partition pool from the list of created partition pools. */ + CSC_Remove_From_List(&PMD_Created_Pools_List, &(pool -> pm_created)); + + /* Decrement the total number of created partition pools. */ + PMD_Total_Pools--; + + /* Pickup the suspended task pointer list. */ + suspend_ptr = pool -> pm_suspension_list; + + /* Walk the chain task(s) currently suspended on the partition pool. */ + preempt = 0; + while (suspend_ptr) + { + + /* Protect against system access. */ + TCT_System_Protect(); + + /* Resume the suspended task. Insure that the status returned is + NU_POOL_DELETED. */ + suspend_ptr -> pm_return_pointer = NU_NULL; + suspend_ptr -> pm_return_status = NU_POOL_DELETED; + + /* Point to the next suspend structure in the link. */ + next_ptr = (PM_SUSPEND *) (suspend_ptr -> pm_suspend_link.cs_next); + + /* Resume the specified task. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> pm_suspended_task, + NU_PARTITION_SUSPEND); + + /* Determine if the next is the same as the current pointer. */ + if (next_ptr == pool -> pm_suspension_list) + + /* Clear the suspension pointer to signal the end of the list + traversal. */ + suspend_ptr = NU_NULL; + else + + /* Move the next pointer into the suspend block pointer. */ + suspend_ptr = next_ptr; + + /* Modify current protection. */ + TCT_Set_Current_Protect(&PMD_List_Protect); + + /* Clear the system protection. */ + TCT_System_Unprotect(); + } + + /* Determine if preemption needs to occur. */ + if (preempt) + + /* Transfer control to system to facilitate preemption. */ + TCT_Control_To_System(); + + /* Release protection against access to the list of created partition + pools. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return a successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PMC_Allocate_Partition */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function allocates a memory partition from the specified */ +/* memory partition pool. If a memory partition is currently */ +/* available, this function is completed immediately. Otherwise, */ +/* if there are no partitions currently available, suspension is */ +/* possible. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* PMCE_Allocate_Partition Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Place on suspend list */ +/* CSC_Priority_Place_On_List Place on priority list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Suspend_Task Suspend calling task */ +/* TCC_Task_Priority Pickup task's priority */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Current_Thread Pickup current thread pointer*/ +/* TCT_System_Protect Protect partition pool */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* pool_ptr Memory partition pool pointer*/ +/* return_pointer Pointer to the destination */ +/* memory pointer */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If service is successful */ +/* NU_NO_PARTITION No partitions are available */ +/* NU_TIMEOUT If timeout on service */ +/* NU_POOL_DELETED If partition pool deleted */ +/* during suspension */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS PMC_Allocate_Partition(NU_PARTITION_POOL *pool_ptr, + VOID **return_pointer, UNSIGNED suspend) +{ + +R1 PM_PCB *pool; /* Pool control block ptr */ +R2 PM_SUSPEND *suspend_ptr; /* Suspend block pointer */ +PM_SUSPEND suspend_block; /* Allocate suspension block */ +R3 PM_HEADER *partition_ptr; /* Pointer to partition */ +TC_TCB *task; /* Task pointer */ +STATUS status; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input pool pointer into internal pointer. */ + pool = (PM_PCB *) pool_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_ALLOCATE_PARTITION_ID, (UNSIGNED) pool, + (UNSIGNED) return_pointer, (UNSIGNED) suspend); + +#endif + + /* Initialize the status as successful. */ + status = NU_SUCCESS; + + /* Protect against simultaneous access to the partition pool. */ + TCT_System_Protect(); + + /* Determine if there is an available memory partition. */ + if (pool -> pm_available) + { + + /* Partition available. */ + + /* Decrement the available count. */ + pool -> pm_available--; + + /* Increment the allocated count. */ + pool -> pm_allocated++; + + /* Unlink the first memory partition and return the pointer to the + caller. */ + partition_ptr = pool -> pm_available_list; + pool -> pm_available_list = partition_ptr -> pm_next_available; + partition_ptr -> pm_next_available = NU_NULL; + + /* Return a memory address to the caller. */ + *return_pointer = (VOID *) (((BYTE_PTR) partition_ptr) + PM_OVERHEAD); + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPartitionPool(RT_PROF_ALLOCATE_PARTITION,pool,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + + } + else + { + + /* A partition is not available. Determine if suspension is + required. */ + if (suspend) + { + + /* Suspension is selected. */ + + /* Increment the number of tasks waiting. */ + pool -> pm_tasks_waiting++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPartitionPool(RT_PROF_ALLOCATE_PARTITION,pool,RT_PROF_WAIT); +#endif /* INCLUDE_PROVIEW */ + /* Setup the suspend block and suspend the calling task. */ + suspend_ptr = &suspend_block; + suspend_ptr -> pm_partition_pool = pool; + suspend_ptr -> pm_suspend_link.cs_next = NU_NULL; + suspend_ptr -> pm_suspend_link.cs_previous = NU_NULL; + task = (TC_TCB *) TCT_Current_Thread(); + suspend_ptr -> pm_suspended_task = task; + + /* Determine if priority or FIFO suspension is associated with the + partition pool. */ + if (pool -> pm_fifo_suspend) + { + + /* FIFO suspension is required. Link the suspend block into + the list of suspended tasks on this partition pool. */ + CSC_Place_On_List((CS_NODE **) + &(pool -> pm_suspension_list), + &(suspend_ptr -> pm_suspend_link)); + } + else + { + + /* Get the priority of the current thread so the suspend block + can be placed in the appropriate place. */ + suspend_ptr -> pm_suspend_link.cs_priority = + TCC_Task_Priority(task); + + CSC_Priority_Place_On_List((CS_NODE **) + &(pool -> pm_suspension_list), + &(suspend_ptr -> pm_suspend_link)); + } + + /* Finally, suspend the calling task. Note that the suspension call + automatically clears the protection on the partition pool. */ + TCC_Suspend_Task((NU_TASK *) task, NU_PARTITION_SUSPEND, + PMC_Cleanup, suspend_ptr, suspend); + + /* Pickup the return status. */ + status = suspend_ptr -> pm_return_status; + *return_pointer = suspend_ptr -> pm_return_pointer; + } + else + { + /* No suspension requested. Simply return an error status. */ + status = NU_NO_PARTITION; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPartitionPool(RT_PROF_ALLOCATE_PARTITION,pool,RT_PROF_FAIL); +#endif /* INCLUDE_PROVIEW */ + } + } + + /* Release protection of the partition pool. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PMC_Deallocate_Partition */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function deallocates a previously allocated partition. If */ +/* there is a task waiting for a partition, the partition is simply */ +/* given to the waiting task and the waiting task is resumed. */ +/* Otherwise, the partition is returned to the partition pool. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* PMCE_Deallocate_Partition Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove from suspend list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_System_Protect Protect partition pool */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* partition Pointer to partition memory */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Added register options, changed */ +/* protection logic to reduce */ +/* overhead, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS PMC_Deallocate_Partition(VOID *partition) +{ + +R1 PM_PCB *pool; /* Pool pointer */ +R3 PM_SUSPEND *suspend_ptr; /* Pointer to suspend block */ +R2 PM_HEADER *header_ptr; /* Pointer to partition hdr */ +STATUS preempt; /* Preemption flag */ +STATUS status; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_DEALLOCATE_PARTITION_ID, (UNSIGNED) partition, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Initialize the status as successful. */ + status = NU_SUCCESS; + + /* Pickup the associated pool's pointer. It is inside the header of + each partition. */ + header_ptr = (PM_HEADER *) (((BYTE_PTR) partition) - PM_OVERHEAD); + pool = header_ptr -> pm_partition_pool; + + /* Protect against simultaneous access to the partition pool. */ + TCT_System_Protect(); + + /* Determine if another task is waiting for a partition from the pool. */ + if (pool -> pm_tasks_waiting) + { + + /* Yes, another task is waiting for a partition from the pool. */ + + /* Decrement the number of tasks waiting counter. */ + pool -> pm_tasks_waiting--; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPartitionPool(RT_PROF_DEALLOCATE_PARTITION,pool,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + + /* Remove the first suspended block from the list. */ + suspend_ptr = pool -> pm_suspension_list; + CSC_Remove_From_List((CS_NODE **) &(pool -> pm_suspension_list), + &(suspend_ptr -> pm_suspend_link)); + + /* Setup the appropriate return value. */ + suspend_ptr -> pm_return_status = NU_SUCCESS; + suspend_ptr -> pm_return_pointer = partition; + + /* Resume the suspended task. */ + preempt = + TCC_Resume_Task((NU_TASK *) suspend_ptr -> pm_suspended_task, + NU_PARTITION_SUSPEND); + + /* Determine if a preempt condition is present. */ + if (preempt) + + /* Transfer control to the system if the resumed task function + detects a preemption condition. */ + TCT_Control_To_System(); + } + else + { + + /* Increment the available partitions counter. */ + pool -> pm_available++; + + /* Decrement the allocated partitions counter. */ + pool -> pm_allocated--; + + /* Place the partition back on the available list. */ + header_ptr -> pm_next_available = pool -> pm_available_list; + pool -> pm_available_list = header_ptr; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpPartitionPool(RT_PROF_DEALLOCATE_PARTITION,pool,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + + } + + /* Release protection of the partition pool. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PMC_Cleanup */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for removing a suspension block */ +/* from a partition pool. It is not called unless a timeout or */ +/* a task terminate is in progress. Note that protection is */ +/* already in effect - the same protection at suspension time. */ +/* */ +/* CALLED BY */ +/* */ +/* TCC_Timeout Task timeout */ +/* TCC_Terminate Task terminate */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove suspend block from */ +/* the suspension list */ +/* */ +/* INPUTS */ +/* */ +/* information Pointer to suspend block */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +VOID PMC_Cleanup(VOID *information) +{ + +PM_SUSPEND *suspend_ptr; /* Suspension block pointer */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Use the information pointer as a suspend pointer. */ + suspend_ptr = (PM_SUSPEND *) information; + + /* By default, indicate that the service timed-out. It really does not + matter if this function is called from a terminate request since + the task does not resume. */ + suspend_ptr -> pm_return_status = NU_TIMEOUT; + suspend_ptr -> pm_return_pointer = NU_NULL; + + /* Decrement the number of tasks waiting counter. */ + (suspend_ptr -> pm_partition_pool) -> pm_tasks_waiting--; + + /* Unlink the suspend block from the suspension list. */ + CSC_Remove_From_List((CS_NODE **) + &((suspend_ptr -> pm_partition_pool) -> pm_suspension_list), + &(suspend_ptr -> pm_suspend_link)); + + /* Return to user mode */ + NU_USER_MODE(); +} + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/pmce.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,426 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* pmce.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* PM - Partition Memory Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the error checking routines for the functions */ +/* in the Partition component. This permits easy removal of error */ +/* checking logic when it is not needed. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* PMCE_Create_Partition_Pool Create a Partition Pool */ +/* PMCE_Delete_Partition_Pool Delete a Partition Pool */ +/* PMCE_Allocate_Partition Allocate a partition from a */ +/* pool */ +/* PMCE_Deallocate_Partition Deallocate a partition from */ +/* a pool */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* pm_extr.h Partition functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed name original error */ +/* checking file and changed */ +/* function interfaces, resulting */ +/* in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "pm_extr.h" /* Partition functions */ + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PMCE_Create_Partition_Pool */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the create partition pool function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* PMC_Create_Partition_Pool Actual create partition pool */ +/* function */ +/* */ +/* INPUTS */ +/* */ +/* pool_ptr Partition pool control block */ +/* pointer */ +/* name Partition pool name */ +/* start_address Starting address of the pool */ +/* pool_size Number of bytes in the pool */ +/* partition_size Number of bytes in each */ +/* partition of the pool */ +/* suspend_type Suspension type */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_POOL Pool control block pointer */ +/* is NULL */ +/* NU_INVALID_MEMORY Pool starting address is NULL*/ +/* NU_INVALID_SIZE Partition size is 0 or it is */ +/* larger than the pool area */ +/* NU_INVALID_SUSPEND Suspension selection is not */ +/* valid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS PMCE_Create_Partition_Pool(NU_PARTITION_POOL *pool_ptr, CHAR *name, + VOID *start_address, UNSIGNED pool_size, + UNSIGNED partition_size, OPTION suspend_type) +{ + +PM_PCB *pool; /* Pool control block ptr */ +STATUS status; /* Completion status */ +UNSIGNED size; /* Adjusted size of partition*/ + + + /* Move input pool pointer into internal pointer. */ + pool = (PM_PCB *) pool_ptr; + + /* Adjust the partition size to something that is evenly divisible by + the number of bytes in an UNSIGNED data type. */ + size = ((partition_size + sizeof(UNSIGNED) - 1)/sizeof(UNSIGNED)) * + sizeof(UNSIGNED); + + /* Check for a NULL partition pool control block pointer or a control + block that is already created. */ + if ((pool == NU_NULL) || (pool -> pm_id == PM_PARTITION_ID)) + + /* Invalid partition pool control block pointer. */ + status = NU_INVALID_POOL; + + else if (start_address == NU_NULL) + + /* Invalid memory pointer. */ + status = NU_INVALID_MEMORY; + + else if ((size == 0) || ((size + PM_OVERHEAD) > pool_size)) + + /* Pool could not even accommodate one partition. */ + status = NU_INVALID_SIZE; + + else if ((suspend_type != NU_FIFO) && (suspend_type != NU_PRIORITY)) + + /* Invalid suspension type. */ + status = NU_INVALID_SUSPEND; + + else + + /* Call the actual service to create the partition pool. */ + status = PMC_Create_Partition_Pool(pool_ptr, name, start_address, + pool_size, partition_size, suspend_type); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PMCE_Delete_Partition_Pool */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the delete partition pool function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* PMC_Delete_Partition_Pool Actual function to delete a */ +/* partition pool */ +/* */ +/* INPUTS */ +/* */ +/* pool_ptr Partition pool control block */ +/* pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_POOL Indicates the supplied pool */ +/* pointer is invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS PMCE_Delete_Partition_Pool(NU_PARTITION_POOL *pool_ptr) +{ + +PM_PCB *pool; /* Pool control block ptr */ +STATUS status; /* Completion status */ + + + /* Move input pool pointer into internal pointer. */ + pool = (PM_PCB *) pool_ptr; + + /* Determine if the partition pool pointer is valid. */ + if ((pool) && (pool -> pm_id == PM_PARTITION_ID)) + + /* Partition pool pointer is valid, call function to delete it. */ + status = PMC_Delete_Partition_Pool(pool_ptr); + + else + + /* Partition pool pointer is invalid, indicate in completion status. */ + status = NU_INVALID_POOL; + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PMCE_Allocate_Partition */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the allocate partition function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* PMC_Allocate_Partition Actual partition allocate */ +/* function */ +/* TCCE_Suspend_Error Check for a task suspension */ +/* error */ +/* */ +/* INPUTS */ +/* */ +/* pool_ptr Memory partition pool pointer*/ +/* return_pointer Pointer to the destination */ +/* memory pointer */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_POOL Indicates the pool pointer */ +/* is invalid */ +/* NU_INVALID_POINTER Indicates the return pointer */ +/* is NULL */ +/* NU_INVALID_SUSPEND Indicates the suspension is */ +/* invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS PMCE_Allocate_Partition(NU_PARTITION_POOL *pool_ptr, + VOID **return_pointer, UNSIGNED suspend) +{ + +PM_PCB *pool; /* Pool control block ptr */ +STATUS status; /* Completion status */ + + + /* Move input pool pointer into internal pointer. */ + pool = (PM_PCB *) pool_ptr; + + /* Determine if partition pool pointer is invalid. */ + if (pool == NU_NULL) + + /* Partition pool pointer is invalid, indicate in completion status. */ + status = NU_INVALID_POOL; + + else if (pool -> pm_id != PM_PARTITION_ID) + + /* Partition pool pointer is invalid, indicate in completion status. */ + status = NU_INVALID_POOL; + + else if (return_pointer == NU_NULL) + + /* Return pointer is invalid. */ + status = NU_INVALID_POINTER; + + else if ((suspend) && (TCCE_Suspend_Error())) + + /* Suspension from a non-task thread. */ + status = NU_INVALID_SUSPEND; + + else + + /* Parameters are valid, call actual function. */ + status = PMC_Allocate_Partition(pool_ptr, return_pointer, suspend); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PMCE_Deallocate_Partition */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the deallocate partition function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* PMC_Deallocate_Partition Deallocate a partition */ +/* */ +/* INPUTS */ +/* */ +/* partition Pointer to partition memory */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_POINTER Indicates the supplied */ +/* partition pointer is NULL, */ +/* or otherwise invalid. */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS PMCE_Deallocate_Partition(VOID *partition) +{ + +PM_PCB *pool; /* Pool pointer */ +PM_HEADER *header_ptr; /* Pointer to partition hdr */ +STATUS status; /* Completion status */ + + + /* Pickup the associated pool's pointer. It is inside the header of + each partition. */ + header_ptr = (PM_HEADER *) (((BYTE_PTR) partition) - PM_OVERHEAD); + + /* Determine if the pointer(s) are NULL. */ + if ((header_ptr == NU_NULL) || (partition == NU_NULL)) + + /* Partition pointer is invalid. */ + status = NU_INVALID_POINTER; + + /* Determine if partition pool pointer is invalid. */ + else if ((pool = header_ptr -> pm_partition_pool) == NU_NULL) + + /* Partition pointer is invalid, indicate in completion status. */ + status = NU_INVALID_POINTER; + + else if (pool -> pm_id != PM_PARTITION_ID) + + /* Partition pool pointer is invalid, indicate in completion status. */ + status = NU_INVALID_POINTER; + + else if (header_ptr -> pm_next_available) + + /* Partition is still linked on the available list- must not be + allocated. */ + status = NU_INVALID_POINTER; + + else + + /* Parameters are valid, call actual function. */ + status = PMC_Deallocate_Partition(partition); + + /* Return the completion status. */ + return(status); +} + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/pmd.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,86 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* pmd.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* PM - Partition Memory Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains global data structures for use within the */ +/* Partition Memory Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* PMD_Created_Pools_List Pointer to the linked-list */ +/* of created partition pools */ +/* PMD_Total_Pools Total number of created */ +/* partition pools */ +/* PMD_List_Protect Partition pool list protect */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* pm_defs.h Partition Management constant*/ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified copyright, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + +#include "pm_defs.h" /* Partition constants */ + + +/* PMD_Created_Pools_List is the head pointer of the linked list of + created partition pools. If the list is NU_NULL, there are no partition + pools created. */ + +CS_NODE *PMD_Created_Pools_List; + + +/* PMD_Total_Pools contains the number of currently created + partition pools. */ + +UNSIGNED PMD_Total_Pools; + + +/* PMD_List_Protect is a list protection structure used to block any other + thread from access to the created partition pool list. */ + +TC_PROTECT PMD_List_Protect; + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/pmf.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,387 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* pmf.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* PM - Partition Memory Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains routines to obtain facts about the Partition */ +/* Memory Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* PMF_Established_Partition_Pools Number of partition pools */ +/* PMF_Partition_Pool_Pointers Build partition pool pointer */ +/* list */ +/* PMF_Partition_Pool_Information Retrieve partition pool info */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* pm_extr.h Partition functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Initial version of partition fact */ +/* service file, version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 11-18-1996 Protected Informational service */ +/* from NULL Control Block pointers */ +/* creating 1.2a. (SPR220) */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "pm_extr.h" /* Partition functions */ +#include "hi_extr.h" /* History functions */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *PMD_Created_Pools_List; +extern UNSIGNED PMD_Total_Pools; +extern TC_PROTECT PMD_List_Protect; + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PMF_Established_Partition_Pools */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the current number of established */ +/* partition pools. Pools previously deleted are no longer */ +/* considered established. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* PMD_Total_Pools Number of established */ +/* partition pools */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED PMF_Established_Partition_Pools(VOID) +{ + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Return the number of established partition pools. */ + return(PMD_Total_Pools); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PMF_Partition_Pool_Pointers */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function builds a list of pool pointers, starting at */ +/* the specified location. The number of pool pointers */ +/* placed in the list is equivalent to the total number of */ +/* pools or the maximum number of pointers specified in the */ +/* call. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect created list */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* pointer_list Pointer to the list area */ +/* maximum_pointers Maximum number of pointers */ +/* */ +/* OUTPUTS */ +/* */ +/* pointers Number of partition pools */ +/* placed in the list */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected pointer retrieval */ +/* loop, resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED PMF_Partition_Pool_Pointers(NU_PARTITION_POOL **pointer_list, + UNSIGNED maximum_pointers) +{ +CS_NODE *node_ptr; /* Pointer to each PCB */ +UNSIGNED pointers; /* Number of pointers in list*/ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Initialize the number of pointers returned. */ + pointers = 0; + + /* Protect against access to the list of created partition pools. */ + TCT_Protect(&PMD_List_Protect); + + /* Loop until all pool pointers are in the list or until the maximum + list size is reached. */ + node_ptr = PMD_Created_Pools_List; + while ((node_ptr) && (pointers < maximum_pointers)) + { + + /* Place the node into the destination list. */ + *pointer_list++ = (NU_PARTITION_POOL *) node_ptr; + + /* Increment the pointers variable. */ + pointers++; + + /* Position the node pointer to the next node. */ + node_ptr = node_ptr -> cs_next; + + /* Determine if the pointer is at the head of the list. */ + if (node_ptr == PMD_Created_Pools_List) + + /* The list search is complete. */ + node_ptr = NU_NULL; + } + + /* Release protection against access to the list of created pools. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the number of pointers in the list. */ + return(pointers); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PMF_Partition_Pool_Information */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns information about the specified partition */ +/* pool. However, if the supplied partition pool pointer is */ +/* invalid, the function simply returns an error status. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_System_Protect Protect partition pool */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* pool_ptr Pointer to the partition pool*/ +/* name Destination for the name */ +/* start_address Destination for the starting */ +/* memory address of the pool */ +/* pool_size Destination for the pool's */ +/* total size */ +/* partition_size Destination for the size of */ +/* each partition */ +/* available Destination for the available*/ +/* number of partitions */ +/* allocated Destination for the number */ +/* of allocated partitions */ +/* suspend_type Destination for the type of */ +/* suspension */ +/* tasks_waiting Destination for the tasks */ +/* waiting count */ +/* first_task Destination for the pointer */ +/* to the first task waiting */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If a valid pool pointer */ +/* is supplied */ +/* NU_INVALID_POOL If pool pointer invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 11-18-1996 Corrected SPR220. */ +/* */ +/*************************************************************************/ +STATUS PMF_Partition_Pool_Information(NU_PARTITION_POOL *pool_ptr, CHAR *name, + VOID **start_address, UNSIGNED *pool_size, + UNSIGNED *partition_size, UNSIGNED *available, + UNSIGNED *allocated, OPTION *suspend_type, + UNSIGNED *tasks_waiting, NU_TASK **first_task) +{ + +PM_PCB *pool; /* Pool control block ptr */ +INT i; /* Working integer variable */ +STATUS completion; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to superisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input pool pointer into internal pointer. */ + pool = (PM_PCB *) pool_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Determine if this partition pool id is valid. */ + if ((pool != NU_NULL) && (pool -> pm_id == PM_PARTITION_ID)) + { + + /* Setup protection of the partition pool. */ + TCT_System_Protect(); + + /* The partition pool pointer is valid. Reflect this in the completion + status and fill in the actual information. */ + completion = NU_SUCCESS; + + /* Copy the partition pool's name. */ + for (i = 0; i < NU_MAX_NAME; i++) + *name++ = pool -> pm_name[i]; + + /* Determine the suspension type. */ + if (pool -> pm_fifo_suspend) + *suspend_type = NU_FIFO; + else + *suspend_type = NU_PRIORITY; + + /* Retrieve information directly out of the control structure. */ + *start_address = pool -> pm_start_address; + *pool_size = pool -> pm_pool_size; + *partition_size = pool -> pm_partition_size; + *available = pool -> pm_available; + *allocated = pool -> pm_allocated; + + /* Retrieve the number of tasks waiting and the pointer to the + first task waiting. */ + *tasks_waiting = pool -> pm_tasks_waiting; + if (pool -> pm_suspension_list) + + /* There is a task waiting. */ + *first_task = (NU_TASK *) + (pool -> pm_suspension_list) -> pm_suspended_task; + else + + /* There are no tasks waiting. */ + *first_task = NU_NULL; + + /* Release protection of the partition pool. */ + TCT_Unprotect(); + } + else + + /* Indicate that the partition pool pointer is invalid. */ + completion = NU_INVALID_POOL; + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the appropriate completion status. */ + return(completion); +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/pmi.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,125 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* pmi.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* PM - Partition Memory Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the initialization routine for the Partition */ +/* Memory Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* PMI_Initialize Partition Management Init. */ +/* */ +/* DEPENDENCIES */ +/* */ +/* pm_defs.h Partition component constants*/ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified copyright, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "pm_defs.h" /* Partition constants */ +#include "pm_extr.h" /* Partition interfaces */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *PMD_Created_Pools_List; +extern UNSIGNED PMD_Total_Pools; +extern TC_PROTECT PMD_List_Protect; + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* PMI_Initialize */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function initializes the data structures that control the */ +/* operation of the Partition Memory component (PM). There are no */ +/* partition pools initially. This routine must be called from */ +/* Supervisor mode in Supervisor/User mode switching kernels. */ +/* */ +/* CALLED BY */ +/* */ +/* INC_Initialize System initialization */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* PMD_Created_Pools_List List of created pools */ +/* PMD_Total_Pools Number of created pools */ +/* PMD_List_Protect Protection for pool list */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +VOID PMI_Initialize(VOID) +{ + + /* Initialize the created partition pool list to NU_NULL. */ + PMD_Created_Pools_List = NU_NULL; + + /* Initialize the total number of created pools to 0. */ + PMD_Total_Pools = 0; + + /* Initialize the list protection structure. */ + PMD_List_Protect.tc_tcb_pointer = NU_NULL; +} + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/profiler.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,100 @@ + +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* profiler.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* PROFILER - Profiler Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file links Nucleus PLUS to optional profiling modules. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* NU_Profiler Eliminates compiler warnings */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* rtprofil.h ProView */ +/* nucprof.h ProView */ +/* rtlib.h ProView */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#ifndef PROFILE_H +#define PROFILE_H + +/* The INCLUDE_PROVIEW macro enables the Nucleus ProView profiler in the + Nucleus PLUS kernel. When PLUS is built with this macro defined, all + applications linked with PLUS must also be linked with the SurroundView + Agent library. Refer to the SurroundView chapter in the port notes for + more details. */ + +#undef INCLUDE_PROVIEW + +#ifdef INCLUDE_PROVIEW + +#include "plus\sm_defs.h" +#include "plus\qu_defs.h" +#include "plus\mb_defs.h" +#include "plus\dm_defs.h" +#include "plus\pi_defs.h" +#include "plus\pm_defs.h" +#include "plus\ev_defs.h" +#include "plus\tm_defs.h" +#include "plus\tc_defs.h" + +#include "svagent\inc\rtprofil.h" +#include "svagent\inc\nuc_prof.h" + +#ifndef PLUS +#define PLUS +#endif + +#include "svagent\inc\rtlib.h" + +VOID _RTProf_TaskStatus(TC_TCB*, unsigned char); +VOID _RTProf_Dispatch_LISR_No_INT_Lock(int); +VOID _RTProf_RegisterLisr(int); +VOID _RTProf_DumpTask(TC_TCB*, unsigned char); +VOID _RTProf_DumpHisr(TC_HCB*, unsigned char); +VOID _RTProf_DumpSema(unsigned char, SM_SCB*, unsigned char); +VOID _RTProf_DumpQueue(unsigned char,QU_QCB*, unsigned char ); +VOID _RTProf_DumpMailBox(unsigned char, MB_MCB*, unsigned char ); +VOID _RTProf_DumpMemoryPool(unsigned char, DM_PCB*, unsigned char ); +VOID _RTProf_DumpPipe(unsigned char, PI_PCB*, unsigned char ); +VOID _RTProf_DumpPartitionPool(unsigned char, PM_PCB*, unsigned char ); +VOID _RTProf_DumpEventGroup(unsigned char, EV_GCB*, unsigned char ); +VOID _RTProf_DumpTimer(unsigned char, TM_APP_TCB*, unsigned char ); +VOID _RTProf_DumpDriver(unsigned char, NU_DRIVER*, unsigned char ); +VOID RTprofUserEvent(rt_uint32, char *); + +#endif /* INCLUDE_PROVIEW */ + +#endif /* PROFILE_H */ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/qu_defs.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,125 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* qu_defs.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* QU - Queue Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains data structure definitions and constants for */ +/* the message Queue component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* QU_QCB Queue control block */ +/* QU_SUSPEND Queue suspension block */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_defs.h Common service definitions */ +/* tc_defs.h Thread Control definitions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* removed protection structure, */ +/* put padding into structure, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "cs_defs.h" /* Common service constants */ +#include "tc_defs.h" /* Thread control constants */ + + +/* Check to see if the file has been included already. */ + +#ifndef QU_DEFS +#define QU_DEFS + + +/* Define constants local to this component. */ + +#define QU_QUEUE_ID 0x51554555UL + + +/* Define the Queue Control Block data type. */ + +typedef struct QU_QCB_STRUCT +{ + CS_NODE qu_created; /* Node for linking to */ + /* created queue list */ + UNSIGNED qu_id; /* Internal QCB ID */ + CHAR qu_name[NU_MAX_NAME]; /* Queue name */ + BOOLEAN qu_fixed_size; /* Fixed-size messages? */ + BOOLEAN qu_fifo_suspend; /* Suspension type flag */ +#if PAD_2 + DATA_ELEMENT qu_padding[PAD_2]; +#endif + UNSIGNED qu_queue_size; /* Total size of queue */ + UNSIGNED qu_messages; /* Messages in queue */ + UNSIGNED qu_message_size; /* Size of each message */ + UNSIGNED qu_available; /* Available words */ + UNSIGNED_PTR qu_start; /* Start of queue area */ + UNSIGNED_PTR qu_end; /* End of queue area + 1 */ + UNSIGNED_PTR qu_read; /* Read pointer */ + UNSIGNED_PTR qu_write; /* Write pointer */ + UNSIGNED qu_tasks_waiting; /* Number of waiting tasks*/ + struct QU_SUSPEND_STRUCT + *qu_urgent_list; /* Urgent message suspend */ + struct QU_SUSPEND_STRUCT + *qu_suspension_list; /* Suspension list */ +} QU_QCB; + + +/* Define the queue suspension structure. This structure is allocated off of + the caller's stack. */ + +typedef struct QU_SUSPEND_STRUCT +{ + CS_NODE qu_suspend_link; /* Link to suspend blocks */ + QU_QCB *qu_queue; /* Pointer to the queue */ + TC_TCB *qu_suspended_task; /* Task suspended */ + UNSIGNED_PTR qu_message_area; /* Pointer to message area*/ + UNSIGNED qu_message_size; /* Message size requested */ + UNSIGNED qu_actual_size; /* Actual size of message */ + STATUS qu_return_status; /* Return status */ +} QU_SUSPEND; + +#endif + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/qu_extr.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,131 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* qu_extr.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* QU - Queue Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains function prototypes of all functions */ +/* accessible to other components. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* qu_defs.h Queue Management constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* modified function prototypes, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "qu_defs.h" /* Include QU constants */ + + +/* Check to see if the file has been included already. */ + +#ifndef QU_EXTR +#define QU_EXTR + + +/* Initialization functions. */ + +VOID QUI_Initialize(VOID); + + +/* Core error checking functions. */ + +STATUS QUCE_Create_Queue(NU_QUEUE *queue_ptr, CHAR *name, + VOID *start_address, UNSIGNED queue_size, + OPTION message_type, UNSIGNED message_size, + OPTION suspend_type); +STATUS QUCE_Delete_Queue(NU_QUEUE *queue_ptr); +STATUS QUCE_Send_To_Queue(NU_QUEUE *queue_ptr, VOID *message, + UNSIGNED size, UNSIGNED suspend); +STATUS QUCE_Receive_From_Queue(NU_QUEUE *queue_ptr, VOID *message, + UNSIGNED size, UNSIGNED *actual_size, UNSIGNED suspend); + +/* Supplemental error checking functions. */ + +STATUS QUSE_Reset_Queue(NU_QUEUE *queue_ptr); +STATUS QUSE_Send_To_Front_Of_Queue(NU_QUEUE *queue_ptr, VOID *message, + UNSIGNED size, UNSIGNED suspend); +STATUS QUSE_Broadcast_To_Queue(NU_QUEUE *queue_ptr, VOID *message, + UNSIGNED size, UNSIGNED suspend); + +/* Core processing functions. */ + +STATUS QUC_Create_Queue(NU_QUEUE *queue_ptr, CHAR *name, + VOID *start_address, UNSIGNED queue_size, + OPTION message_type, UNSIGNED message_size, + OPTION suspend_type); +STATUS QUC_Delete_Queue(NU_QUEUE *queue_ptr); +STATUS QUC_Send_To_Queue(NU_QUEUE *queue_ptr, VOID *message, + UNSIGNED size, UNSIGNED suspend); +STATUS QUC_Receive_From_Queue(NU_QUEUE *queue_ptr, VOID *message, + UNSIGNED size, UNSIGNED *actual_size, UNSIGNED suspend); + +/* Supplemental processing functions. */ + +STATUS QUS_Reset_Queue(NU_QUEUE *queue_ptr); +STATUS QUS_Send_To_Front_Of_Queue(NU_QUEUE *queue_ptr, VOID *message, + UNSIGNED size, UNSIGNED suspend); +STATUS QUS_Broadcast_To_Queue(NU_QUEUE *queue_ptr, VOID *message, + UNSIGNED size, UNSIGNED suspend); + +/* Information gathering functions. */ + + +UNSIGNED QUF_Established_Queues(VOID); +STATUS QUF_Queue_Information(NU_QUEUE *queue_ptr, CHAR *name, + VOID **start_address, UNSIGNED *queue_size, + UNSIGNED *available, UNSIGNED *messages, + OPTION *message_type, UNSIGNED *message_size, + OPTION *suspend_type, UNSIGNED *tasks_waiting, + NU_TASK **first_task); +UNSIGNED QUF_Queue_Pointers(NU_QUEUE **pointer_list, + UNSIGNED maximum_pointers); + +#endif + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/quc.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,1496 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* quc.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* QU - Queue Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the core routines for the Queue management */ +/* component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* QUC_Create_Queue Create a message queue */ +/* QUC_Delete_Queue Delete a message queue */ +/* QUC_Send_To_Queue Send message to a queue */ +/* QUC_Receive_From_Queue Receive a message from queue */ +/* QUC_Cleanup Cleanup on timeout or a */ +/* terminate condition */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* qu_extr.h Queue functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected pointer retrieval */ +/* loop, resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 11-01-1993 Corrected a problem with fixed- */ +/* size queues of a size equal to */ +/* one message, resulting in */ +/* version 1.0b */ +/* 11-01-1993 Verified version 1.0b */ +/* 03-01-1994 Moved non-core functions into */ +/* supplemental files, changed */ +/* function interfaces to match */ +/* those in prototype, added */ +/* register options, changed */ +/* protection logic to reduce */ +/* overhead, corrected bug in */ +/* queue reset, optimized item */ +/* copy loops, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 01-28-1998 Corrected SPR412 resulting in */ +/* version 1.2a. */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "qu_extr.h" /* Queue functions */ +#include "hi_extr.h" /* History functions */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *QUD_Created_Queues_List; +extern UNSIGNED QUD_Total_Queues; +extern TC_PROTECT QUD_List_Protect; + + +/* Define internal component function prototypes. */ + +VOID QUC_Cleanup(VOID *information); + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* QUC_Create_Queue */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function creates a queue and then places it on the list */ +/* of created queues. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* QUCE_Create_Queue Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Add node to linked-list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect created list */ +/* TCT_Unprotect Un-protect data structure */ +/* */ +/* INPUTS */ +/* */ +/* queue_ptr Queue control block pointer */ +/* name Queue name */ +/* start_address Starting address of actual */ +/* queue area */ +/* queue_size Total size of queue */ +/* message_type Type of message supported by */ +/* the queue (fixed/variable) */ +/* message_size Size of message. Variable */ +/* message-length queues, this*/ +/* represents the maximum size*/ +/* suspend_type Suspension type */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS QUC_Create_Queue(NU_QUEUE *queue_ptr, CHAR *name, + VOID *start_address, UNSIGNED queue_size, + OPTION message_type, UNSIGNED message_size, + OPTION suspend_type) +{ + +R1 QU_QCB *queue; /* Queue control block ptr */ +INT i; /* Working index variable */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input queue pointer into internal pointer. */ + queue = (QU_QCB *) queue_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_CREATE_QUEUE_ID, (UNSIGNED) queue, + (UNSIGNED) name, (UNSIGNED) start_address); + +#endif + + /* First, clear the queue ID just in case it is an old Queue + Control Block. */ + queue -> qu_id = 0; + + /* Fill in the queue name. */ + for (i = 0; i < NU_MAX_NAME; i++) + queue -> qu_name[i] = name[i]; + + /* Setup the queue suspension type. */ + if (suspend_type == NU_FIFO) + + /* FIFO suspension is selected, setup the flag accordingly. */ + queue -> qu_fifo_suspend = NU_TRUE; + + else + + /* Priority suspension is selected. */ + queue -> qu_fifo_suspend = NU_FALSE; + + /* Setup the queue message type. */ + if (message_type == NU_FIXED_SIZE) + + /* Fixed-size messages are required. */ + queue -> qu_fixed_size = NU_TRUE; + else + + /* Variable-size messages are required. */ + queue -> qu_fixed_size = NU_FALSE; + + /* Setup the message size. */ + queue -> qu_message_size = message_size; + + /* Clear the messages counter. */ + queue -> qu_messages = 0; + + /* Setup the actual queue parameters. */ + queue -> qu_queue_size = queue_size; + + /* If the queue supports fixed-size messages, make sure that the queue + size is an even multiple of the message size. */ + if (queue -> qu_fixed_size) + + /* Adjust the area of the queue being used. */ + queue_size = (queue_size / message_size) * message_size; + + queue -> qu_available = queue_size; + queue -> qu_start = (UNSIGNED *) start_address; + queue -> qu_end = queue -> qu_start + queue_size; + queue -> qu_read = (UNSIGNED *) start_address; + queue -> qu_write = (UNSIGNED *) start_address; + + /* Clear the suspension list pointer. */ + queue -> qu_suspension_list = NU_NULL; + + /* Clear the number of tasks waiting on the queue counter. */ + queue -> qu_tasks_waiting = 0; + + /* Clear the urgent message list pointer. */ + queue -> qu_urgent_list = NU_NULL; + + /* Initialize link pointers. */ + queue -> qu_created.cs_previous = NU_NULL; + queue -> qu_created.cs_next = NU_NULL; + + /* Protect against access to the list of created queues. */ + TCT_Protect(&QUD_List_Protect); + + /* At this point the queue is completely built. The ID can now be + set and it can be linked into the created queue list. */ + queue -> qu_id = QU_QUEUE_ID; + + /* Link the queue into the list of created queues and increment the + total number of queues in the system. */ + CSC_Place_On_List(&QUD_Created_Queues_List, &(queue -> qu_created)); + QUD_Total_Queues++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpQueue(RT_PROF_CREATE_QUEUE,queue,RT_PROF_OK); +#endif + + /* Release protection against access to the list of created queues. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* QUC_Delete_Queue */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function deletes a queue and removes it from the list of */ +/* created queues. All tasks suspended on the queue are */ +/* resumed. Note that this function does not free the memory */ +/* associated with the queue. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* QUCE_Delete_Queue Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove node from list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Protect Protect created list */ +/* TCT_Set_Current_Protect Setup current protect pointer*/ +/* TCT_System_Protect Protect against system access*/ +/* TCT_System_Unprotect Release system protection */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* queue_ptr Queue control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS QUC_Delete_Queue(NU_QUEUE *queue_ptr) +{ + +R1 QU_QCB *queue; /* Queue control block ptr */ +QU_SUSPEND *suspend_ptr; /* Suspend block pointer */ +QU_SUSPEND *next_ptr; /* Next suspend block pointer*/ +STATUS preempt; /* Status for resume call */ +NU_SUPERV_USER_VARIABLES + + /* Move input queue pointer into internal pointer. */ + queue = (QU_QCB *) queue_ptr; + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_DELETE_QUEUE_ID, (UNSIGNED) queue, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Protect against access to the queue. */ + TCT_System_Protect(); + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpQueue(RT_PROF_DELETE_QUEUE,queue,RT_PROF_OK); +#endif + + /* Clear the queue ID. */ + queue -> qu_id = 0; + + /* Release protection. */ + TCT_Unprotect(); + + /* Protect against access to the list of created queues. */ + TCT_Protect(&QUD_List_Protect); + + /* Remove the queue from the list of created queues. */ + CSC_Remove_From_List(&QUD_Created_Queues_List, &(queue -> qu_created)); + + /* Decrement the total number of created queues. */ + QUD_Total_Queues--; + + /* Pickup the suspended task pointer list. */ + suspend_ptr = queue -> qu_suspension_list; + + /* Walk the chain task(s) currently suspended on the queue. */ + preempt = 0; + while (suspend_ptr) + { + + /* Protect against system access. */ + TCT_System_Protect(); + + /* Resume the suspended task. Insure that the status returned is + NU_QUEUE_DELETED. */ + suspend_ptr -> qu_return_status = NU_QUEUE_DELETED; + + /* Point to the next suspend structure in the link. */ + next_ptr = (QU_SUSPEND *) (suspend_ptr -> qu_suspend_link.cs_next); + + /* Resume the specified task. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> qu_suspended_task, + NU_QUEUE_SUSPEND); + + /* Determine if the next is the same as the head pointer. */ + if (next_ptr == queue -> qu_suspension_list) + + /* Clear the suspension pointer to signal the end of the list + traversal. */ + suspend_ptr = NU_NULL; + else + + /* Position suspend pointer to the next pointer. */ + suspend_ptr = next_ptr; + + /* Modify current protection. */ + TCT_Set_Current_Protect(&QUD_List_Protect); + + /* Clear the system protection. */ + TCT_System_Unprotect(); + } + + /* Pickup the urgent message suspension list. */ + suspend_ptr = queue -> qu_urgent_list; + + /* Walk the chain task(s) currently suspended on the queue. */ + while (suspend_ptr) + { + + /* Protect against system access. */ + TCT_System_Protect(); + + /* Resume the suspended task. Insure that the status returned is + NU_QUEUE_DELETED. */ + suspend_ptr -> qu_return_status = NU_QUEUE_DELETED; + + /* Point to the next suspend structure in the link. */ + next_ptr = (QU_SUSPEND *) (suspend_ptr -> qu_suspend_link.cs_next); + + /* Resume the specified task. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> qu_suspended_task, + NU_QUEUE_SUSPEND); + + /* Determine if the next is the same as the head pointer. */ + if (next_ptr == queue -> qu_urgent_list) + + /* Clear the suspension pointer to signal the end of the list + traversal. */ + suspend_ptr = NU_NULL; + else + + /* Position to the next suspend block in the list. */ + suspend_ptr = next_ptr; + + /* Modify current protection. */ + TCT_Set_Current_Protect(&QUD_List_Protect); + + /* Clear the system protection. */ + TCT_System_Unprotect(); + } + + /* Determine if preemption needs to occur. */ + if (preempt) + + /* Transfer control to system to facilitate preemption. */ + TCT_Control_To_System(); + + /* Release protection against access to the list of created queues. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return a successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* QUC_Send_To_Queue */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sends a message to the specified queue. The */ +/* message length is determined by the caller. If there are one */ +/* or more tasks suspended on the queue for a message, the message */ +/* is copied into the message area of the first waiting task. If */ +/* the task's request is satisfied, it is resumed. Otherwise, if */ +/* the queue cannot hold the message, suspension of the calling */ +/* task is an option of the caller. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* QUCE_Send_To_Queue Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Place on suspend list */ +/* CSC_Priority_Place_On_List Place on priority list */ +/* CSC_Remove_From_List Remove from suspend list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* TCC_Suspend_Task Suspend calling task */ +/* TCC_Task_Priority Pickup task's priority */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Current_Thread Pickup current thread pointer*/ +/* TCT_System_Protect Protect queue */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* queue_ptr Queue control block pointer */ +/* message Pointer to message to send */ +/* size Size of message to send */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If service is successful */ +/* NU_QUEUE_FULL If queue is currently full */ +/* NU_TIMEOUT If timeout on service expires*/ +/* NU_QUEUE_DELETED If queue was deleted during */ +/* suspension */ +/* NU_QUEUE_RESET If queue was reset during */ +/* suspension */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, optimized copy loop, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS QUC_Send_To_Queue(NU_QUEUE *queue_ptr, VOID *message, UNSIGNED size, + UNSIGNED suspend) +{ + +R1 QU_QCB *queue; /* Queue control block ptr */ +QU_SUSPEND suspend_block; /* Allocate suspension block */ +QU_SUSPEND *suspend_ptr; /* Pointer to suspend block */ +R3 UNSIGNED_PTR source; /* Pointer to source */ +R4 UNSIGNED_PTR destination; /* Pointer to destination */ +UNSIGNED copy_size; /* Partial copy size */ +R2 INT i; /* Working counter */ +TC_TCB *task; /* Task pointer */ +STATUS preempt; /* Preempt flag */ +STATUS status; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input queue pointer into internal pointer. */ + queue = (QU_QCB *) queue_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_SEND_TO_QUEUE_ID, (UNSIGNED) queue, + (UNSIGNED) message, (UNSIGNED) size); + +#endif + + /* Initialize the status as successful. */ + status = NU_SUCCESS; + + /* Protect against simultaneous access to the queue. */ + TCT_System_Protect(); + + /* Determine if an extra word of overhead needs to be added to the + calculation. */ + if (queue -> qu_fixed_size) + + /* No overhead. */ + i = 0; + else + { + /* Variable messages have one additional word of overhead. */ + i = 1; + + /* Make special check to see if a suspension needs to be + forced for a variable length message. */ + if ((queue -> qu_suspension_list) && (queue -> qu_messages)) + { + + /* Pickup task control block pointer. */ + task = (TC_TCB *) TCT_Current_Thread(); + + /* Now we know that there are other task(s) are suspended trying + to send a variable length message. Determine whether or not + a suspension should be forced. */ + if ((queue -> qu_fifo_suspend) || + (suspend == NU_NO_SUSPEND) || + ((queue -> qu_suspension_list) -> qu_suspend_link.cs_priority <= + TCC_Task_Priority(task))) + + /* Bump the computed size to avoid placing the new variable + length message ahead of the suspended tasks. */ + i = (INT) queue -> qu_available; + } + } + + /* Determine if there is enough room in the queue for the message. The + extra logic is to prevent a variable-length message from sn*/ + if (queue -> qu_available < (size + i)) + { + + /* Queue does not have room for the message. Determine if + suspension is required. */ + if (suspend) + { + + /* Suspension is requested. */ + + /* Increment the number of tasks waiting. */ + queue -> qu_tasks_waiting++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpQueue(RT_PROF_SEND_TO_QUEUE,queue,RT_PROF_WAIT); +#endif + + /* Setup the suspend block and suspend the calling task. */ + suspend_ptr = &suspend_block; + suspend_ptr -> qu_queue = queue; + suspend_ptr -> qu_suspend_link.cs_next = NU_NULL; + suspend_ptr -> qu_suspend_link.cs_previous = NU_NULL; + suspend_ptr -> qu_message_area = (UNSIGNED_PTR) message; + suspend_ptr -> qu_message_size = size; + task = (TC_TCB *) TCT_Current_Thread(); + suspend_ptr -> qu_suspended_task = task; + + /* Determine if priority or FIFO suspension is associated with the + queue. */ + if (queue -> qu_fifo_suspend) + { + + /* FIFO suspension is required. Link the suspend block into + the list of suspended tasks on this queue. */ + CSC_Place_On_List((CS_NODE **) &(queue -> qu_suspension_list), + &(suspend_ptr -> qu_suspend_link)); + } + else + { + + /* Get the priority of the current thread so the suspend block + can be placed in the appropriate place. */ + suspend_ptr -> qu_suspend_link.cs_priority = + TCC_Task_Priority(task); + + CSC_Priority_Place_On_List((CS_NODE **) + &(queue -> qu_suspension_list), + &(suspend_ptr -> qu_suspend_link)); + } + + /* Finally, suspend the calling task. Note that the suspension call + automatically clears the protection on the queue. */ + TCC_Suspend_Task((NU_TASK *) task, NU_QUEUE_SUSPEND, + QUC_Cleanup, suspend_ptr, suspend); + + /* Pickup the return status. */ + status = suspend_ptr -> qu_return_status; + } + else + { + + /* Return a status of NU_QUEUE_FULL because there is no + room in the queue for the message. */ + status = NU_QUEUE_FULL; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpQueue(RT_PROF_SEND_TO_QUEUE,queue,RT_PROF_FAIL); +#endif + + } + } + else + { + + /* Determine if a task is waiting on an empty queue. */ + if ((queue -> qu_suspension_list) && (queue -> qu_messages == 0)) + { + + /* Task is waiting on an empty queue for a message. */ + + /* Decrement the number of tasks waiting on queue. */ + queue -> qu_tasks_waiting--; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpQueue(RT_PROF_SEND_TO_QUEUE,queue,RT_PROF_OK); +#endif + + /* Remove the first suspended block from the list. */ + suspend_ptr = queue -> qu_suspension_list; + CSC_Remove_From_List((CS_NODE **) &(queue -> qu_suspension_list), + &(suspend_ptr -> qu_suspend_link)); + + /* Setup the source and destination pointers. */ + source = (UNSIGNED_PTR) message; + destination = suspend_ptr -> qu_message_area; + + /* Initialize the return status. */ + suspend_ptr -> qu_return_status = NU_SUCCESS; + + /* Loop to actually copy the message. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + + /* Return the size of the message copied. */ + suspend_ptr -> qu_actual_size = size; + + /* Wakeup the waiting task and check for preemption. */ + preempt = + TCC_Resume_Task((NU_TASK *) suspend_ptr -> qu_suspended_task, + NU_QUEUE_SUSPEND); + + /* Determine if preemption needs to take place. */ + if (preempt) + + /* Transfer control to the system if the resumed task function + detects a preemption condition. */ + TCT_Control_To_System(); + } + else + { + + /* There is enough room in the queue and no task is waiting. */ + + /* Setup the source pointer. */ + source = (UNSIGNED_PTR) message; + destination = queue -> qu_write; + + /* Process according to the type of message supported. */ + if (queue -> qu_fixed_size) + { + + /* Fixed-size messages are supported by this queue. */ + + /* Loop to copy the message into the queue area. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + else + { + + /* Variable-size messages are supported. Processing must + check for queue wrap-around conditions. */ + + /* Place message size in first location. */ + *(destination++) = size; + + /* Check for a wrap-around condition on the queue. */ + if (destination >= queue -> qu_end) + + /* Wrap the write pointer back to the top of the queue + area. */ + destination = queue -> qu_start; + + /* Decrement the number of words remaining by 1 for this + extra word of overhead. */ + queue -> qu_available--; + + /* Calculate the number of words remaining from the write + pointer to the bottom of the queue. */ + copy_size = queue -> qu_end - destination; + + /* Determine if the message needs to be wrapped around the + edge of the queue area. */ + if (copy_size >= size) + { + + /* Copy the whole message at once. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + else + { + + /* Copy the first half of the message. */ + i = (INT) copy_size; + do + { + *(destination) = *(source++); + if ((--i) == 0) + break; + destination++; + } while (1); + + /* Copy the second half of the message. */ + destination = queue -> qu_start; + i = (INT) (size - copy_size); + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + } + + /* Check again for wrap-around condition on the write pointer. */ + if (destination >= queue -> qu_end) + + /* Move the write pointer to the top of the queue area. */ + queue -> qu_write = queue -> qu_start; + else + + /* Simply copy the last position of the destination pointer + into the write pointer. */ + queue -> qu_write = destination; + + /* Decrement the number of available words. */ + queue -> qu_available = queue -> qu_available - size; + + /* Increment the number of messages in the queue. */ + queue -> qu_messages++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpQueue(RT_PROF_SEND_TO_QUEUE,queue,RT_PROF_OK); +#endif + + } + } + + /* Release protection against access to the queue. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* QUC_Receive_From_Queue */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function receives a message from the specified queue. The */ +/* size of the message is specified by the caller. If there is a */ +/* message currently in the queue, the message is removed from the */ +/* queue and placed in the caller's area. Suspension is possible */ +/* if the request cannot be satisfied. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* QUCE_Receive_From_Queue Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Place on suspend list */ +/* CSC_Priority_Place_On_List Place on priority list */ +/* CSC_Remove_From_List Remove from suspend list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* TCC_Suspend_Task Suspend calling task */ +/* TCC_Task_Priority Pickup task's priority */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Current_Thread Pickup current thread pointer*/ +/* TCT_System_Protect Protect queue */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* queue_ptr Queue control block pointer */ +/* message Pointer to message to send */ +/* size Size of the message */ +/* actual_size Size of message received */ +/* suspend Suspension option if empty */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If service is successful */ +/* NU_QUEUE_EMPTY If queue is currently empty */ +/* NU_TIMEOUT If timeout on service expires*/ +/* NU_QUEUE_DELETED If queue was deleted during */ +/* suspension */ +/* NU_QUEUE_RESET If queue was reset during */ +/* suspension */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 11-01-1993 Corrected a problem resuming a */ +/* task suspended on a full queue */ +/* that only has a capacity of a */ +/* single message, resulting in */ +/* version 1.0b */ +/* 11-01-1993 Verified version 1.0b */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, optimized copy loop, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 01-28-1998 Corrected SPR412. */ +/* */ +/*************************************************************************/ +STATUS QUC_Receive_From_Queue(NU_QUEUE *queue_ptr, VOID *message, + UNSIGNED size, UNSIGNED *actual_size, UNSIGNED suspend) +{ + +R1 QU_QCB *queue; /* Queue control block ptr */ +QU_SUSPEND suspend_block; /* Allocate suspension block */ +QU_SUSPEND *suspend_ptr; /* Pointer to suspend block */ +R3 UNSIGNED_PTR source; /* Pointer to source */ +R4 UNSIGNED_PTR destination; /* Pointer to destination */ +TC_TCB *task; /* Task pointer */ +UNSIGNED copy_size; /* Number of words to copy */ +R2 INT i; /* Working counter */ +STATUS preempt; /* Preemption flag */ +STATUS status; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + + /* Move input queue pointer into internal pointer. */ + queue = (QU_QCB *) queue_ptr; + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_RECEIVE_FROM_QUEUE_ID, (UNSIGNED) queue, + (UNSIGNED) message, (UNSIGNED) size); + +#endif + + /* Initialize the status as successful. */ + status = NU_SUCCESS; + + /* Protect against simultaneous access to the queue. */ + TCT_System_Protect(); + + /* Determine if an urgent message request is currently suspended. */ + if (queue -> qu_urgent_list) + { + + /* If so, copy the message from the suspended request block and + resume the associated task. */ + + /* Decrement the number of tasks waiting on queue. */ + queue -> qu_tasks_waiting--; + + /* Remove the first suspended block from the list. */ + suspend_ptr = queue -> qu_urgent_list; + CSC_Remove_From_List((CS_NODE **) &(queue -> qu_urgent_list), + &(suspend_ptr -> qu_suspend_link)); + + /* Setup the source and destination pointers. */ + destination = (UNSIGNED_PTR) message; + source = suspend_ptr -> qu_message_area; + + /* Initialize the return status. */ + suspend_ptr -> qu_return_status = NU_SUCCESS; + + /* Loop to actually copy the message. */ + i = (INT) suspend_ptr -> qu_message_size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + + /* Return the size of the message copied. */ + *actual_size = suspend_ptr -> qu_message_size; + + /* Wakeup the waiting task and check for preemption. */ + preempt = + TCC_Resume_Task((NU_TASK *) suspend_ptr -> qu_suspended_task, + NU_QUEUE_SUSPEND); + + /* Determine if preemption needs to take place. */ + if (preempt) + + /* Transfer control to the system if the resumed task function + detects a preemption condition. */ + TCT_Control_To_System(); + } + + /* Determine if there are messages in the queue. */ + else if (queue -> qu_messages) + { + + /* Copy message from queue into the caller's area. */ + + /* Setup the source and destination pointers. */ + source = queue -> qu_read; + destination = (UNSIGNED_PTR) message; + + /* Process according to the type of message supported by the queue. */ + if (queue -> qu_fixed_size) + { + + /* Queue supports fixed-size messages. */ + + /* Copy the message from the queue area into the destination. */ + i = (INT) size; + do + { + *(destination) = *(source++); + if ((--i) == 0) + break; + destination++; + } while (1); + } + else + { + + /* Queue supports variable-size messages. */ + + /* Variable length message size is actually in the queue area. */ + size = *(source++); + + /* Check for a wrap-around condition on the queue. */ + if (source >= queue -> qu_end) + + /* Wrap the read pointer back to the top of the queue + area. */ + source = queue -> qu_start; + + /* Increment the number of available words in the queue. */ + queue -> qu_available++; + + /* Calculate the number of words remaining from the read pointer + to the bottom of the queue. */ + copy_size = queue -> qu_end - source; + + /* Determine if the message needs to be wrapped around the + edge of the queue area. */ + if (copy_size >= size) + { + + /* Copy the whole message at once. */ + i = (INT) size; + do + { + *(destination) = *(source++); + if ((--i) == 0) + break; + destination++; + } while (1); + } + else + { + + /* Copy the first half of the message. */ + i = (INT) copy_size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + + /* Copy the second half of the message. */ + source = queue -> qu_start; + i = (INT) (size - copy_size); + do + { + *(destination) = *(source++); + if ((--i) == 0) + break; + destination++; + } while (1); + } + } + + /* Check again for wrap-around condition on the read pointer. */ + if (source >= queue -> qu_end) + + /* Move the read pointer to the top of the queue area. */ + queue -> qu_read = queue -> qu_start; + else + + /* Move the read pointer to where the copy left off. */ + queue -> qu_read = source; + + /* Increment the number of available words. */ + queue -> qu_available = queue -> qu_available + size; + + /* Decrement the number of messages in the queue. */ + queue -> qu_messages--; + + /* Return the number of words received. */ + *actual_size = size; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpQueue(RT_PROF_RECEIVE_FROM_QUEUE,queue,RT_PROF_OK); +#endif + + /* Determine if any tasks suspended on a full queue can be woken + up. */ + if (queue -> qu_suspension_list) + { + + /* Overhead of each queue message. */ + if (!queue -> qu_fixed_size) + + i = 1; + else + + i = 0; + + /* Pickup the suspension list and examine suspension blocks + to see if the message could now fit in the queue. */ + suspend_ptr = queue -> qu_suspension_list; + preempt = NU_FALSE; + while ((suspend_ptr) && + ((suspend_ptr -> qu_message_size + i) <= queue -> qu_available)) + { + + /* Place the suspended task's message into the queue. */ + + /* Setup the source and destination pointers. */ + source = suspend_ptr -> qu_message_area; + destination = queue -> qu_write; + size = suspend_ptr -> qu_message_size; + + /* Process according to the type of message supported. */ + if (queue -> qu_fixed_size) + { + + /* Fixed-size messages are supported by this queue. */ + + /* Loop to copy the message into the queue area. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + else + { + + /* Variable-size messages are supported. Processing must + check for queue wrap-around conditions. */ + + /* Place message size in first location. */ + *(destination++) = size; + + /* Check for a wrap-around condition on the queue. */ + if (destination >= queue -> qu_end) + + /* Wrap the write pointer back to the top of the queue + area. */ + destination = queue -> qu_start; + + /* Decrement the number of words remaining by 1 for this + extra word of overhead. */ + queue -> qu_available--; + + /* Calculate the number of words remaining from the write + pointer to the bottom of the queue. */ + copy_size = queue -> qu_end - destination; + + /* Determine if the message needs to be wrapped around the + edge of the queue area. */ + if (copy_size >= size) + { + + /* Copy the whole message at once. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while(1); + } + else + { + + /* Copy the first half of the message. */ + i = (INT) copy_size; + do + { + *(destination) = *(source++); + if ((--i) == 0) + break; + destination++; + } while (1); + + /* Copy the second half of the message. */ + destination = queue -> qu_start; + i = (INT) (size - copy_size); + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + } + + /* Check again for wrap-around condition on the write + pointer. */ + if (destination >= queue -> qu_end) + + /* Move the write pointer to the top of the queue area. */ + queue -> qu_write = queue -> qu_start; + else + + /* Simply copy the last position of the destination pointer + into the write pointer. */ + queue -> qu_write = destination; + + /* Decrement the number of available words. */ + queue -> qu_available = queue -> qu_available - size; + + /* Increment the number of messages in the queue. */ + queue -> qu_messages++; + + /* Decrement the number of tasks waiting counter. */ + queue -> qu_tasks_waiting--; + + /* Remove the first suspended block from the list. */ + CSC_Remove_From_List((CS_NODE **) + &(queue -> qu_suspension_list), + &(suspend_ptr -> qu_suspend_link)); + + /* Return a successful status. */ + suspend_ptr -> qu_return_status = NU_SUCCESS; + + /* Resume the suspended task. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> qu_suspended_task, + NU_QUEUE_SUSPEND); + + /* Setup suspend pointer to the head of the list. */ + suspend_ptr = queue -> qu_suspension_list; + + /* Overhead of each queue message. */ + if (!queue -> qu_fixed_size) + + i = 1; + else + + i = 0; + } + + /* Determine if a preempt condition is present. */ + if (preempt) + + /* Transfer control to the system if the resumed task function + detects a preemption condition. */ + TCT_Control_To_System(); + } + } + else + { + + /* Queue is empty. Determine if the task wants to suspend. */ + if (suspend) + { + + /* Increment the number of tasks waiting on the queue counter. */ + queue -> qu_tasks_waiting++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpQueue(RT_PROF_RECEIVE_FROM_QUEUE,queue,RT_PROF_WAIT); +#endif + + /* Setup the suspend block and suspend the calling task. */ + suspend_ptr = &suspend_block; + suspend_ptr -> qu_queue = queue; + suspend_ptr -> qu_suspend_link.cs_next = NU_NULL; + suspend_ptr -> qu_suspend_link.cs_previous = NU_NULL; + suspend_ptr -> qu_message_area = (UNSIGNED_PTR) message; + suspend_ptr -> qu_message_size = size; + task = (TC_TCB *) TCT_Current_Thread(); + suspend_ptr -> qu_suspended_task = task; + + /* Determine if priority or FIFO suspension is associated with the + queue. */ + if (queue -> qu_fifo_suspend) + { + + /* FIFO suspension is required. Link the suspend block into + the list of suspended tasks on this queue. */ + CSC_Place_On_List((CS_NODE **) &(queue -> qu_suspension_list), + &(suspend_ptr -> qu_suspend_link)); + } + else + { + + /* Get the priority of the current thread so the suspend block + can be placed in the appropriate place. */ + suspend_ptr -> qu_suspend_link.cs_priority = + TCC_Task_Priority(task); + + CSC_Priority_Place_On_List((CS_NODE **) + &(queue -> qu_suspension_list), + &(suspend_ptr -> qu_suspend_link)); + } + + /* Finally, suspend the calling task. Note that the suspension call + automatically clears the protection on the queue. */ + TCC_Suspend_Task((NU_TASK *) task, NU_QUEUE_SUSPEND, + QUC_Cleanup, suspend_ptr, suspend); + + /* Pickup the status of the request. */ + status = suspend_ptr -> qu_return_status; + *actual_size = suspend_ptr -> qu_actual_size; + } + else + { + + /* Return a status of NU_QUEUE_EMPTY because there are no + messages in the queue. */ + status = NU_QUEUE_EMPTY; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpQueue(RT_PROF_RECEIVE_FROM_QUEUE,queue,RT_PROF_FAIL); +#endif + + } + } + + /* Release protection against access to the queue. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* QUC_Cleanup */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for removing a suspension block */ +/* from a queue. It is not called unless a timeout or a task */ +/* terminate is in progress. Note that protection is already in */ +/* effect - the same protection at suspension time. This routine */ +/* must be called from Supervisor mode in Supervisor/User mode */ +/* switching kernels. */ +/* */ +/* CALLED BY */ +/* */ +/* TCC_Timeout Task timeout */ +/* TCC_Terminate Task terminate */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove suspend block from */ +/* the suspension list */ +/* */ +/* INPUTS */ +/* */ +/* information Pointer to suspend block */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +VOID QUC_Cleanup(VOID *information) +{ + +QU_SUSPEND *suspend_ptr; /* Suspension block pointer */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Use the information pointer as a suspend pointer. */ + suspend_ptr = (QU_SUSPEND *) information; + + /* By default, indicate that the service timed-out. It really does not + matter if this function is called from a terminate request since + the task does not resume. */ + suspend_ptr -> qu_return_status = NU_TIMEOUT; + + /* Decrement the number of tasks waiting counter. */ + (suspend_ptr -> qu_queue) -> qu_tasks_waiting--; + + /* Unlink the suspend block from the suspension list. */ + if ((suspend_ptr -> qu_queue) -> qu_urgent_list) + { + /* Unlink the suspend block from the suspension list. */ + CSC_Remove_From_List((CS_NODE **) + &((suspend_ptr -> qu_queue) -> qu_urgent_list), + &(suspend_ptr -> qu_suspend_link)); + } + else + { + /* Unlink the suspend block from the suspension list. */ + CSC_Remove_From_List((CS_NODE **) + &((suspend_ptr -> qu_queue) -> qu_suspension_list), + &(suspend_ptr -> qu_suspend_link)); + } + + /* Return to user mode */ + NU_USER_MODE(); +} + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/quce.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,488 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* quce.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* QU - Queue Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains error checking routines for core functions */ +/* of the Queue component. This permits easy removal of error */ +/* checking logic when it is not needed. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* QUCE_Create_Queue Create a queue */ +/* QUCE_Delete_Queue Delete a queue */ +/* QUCE_Send_To_Queue Send a queue message */ +/* QUCE_Receive_From_Queue Receive a queue message */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* qu_extr.h Queue functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Split original error checking */ +/* file and changed function */ +/* interfaces, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 10-28-1997 Modified QUCE_Receive_From_Queue */ +/* to correct SPR142. This */ +/* created version 1.2a. */ +/* 03-24-1998 Released version 1.3. */ +/* 06-04-1998 Modified QUCE_Send_To_Queue to */ +/* check for a size of 0, created */ +/* version 1.3a. (SPR493) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "qu_extr.h" /* Queue functions */ + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* QUCE_Create_Queue */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the queue create function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* QUC_Create_Queue Actual create queue function */ +/* */ +/* INPUTS */ +/* */ +/* queue_ptr Queue control block pointer */ +/* name Queue name */ +/* start_address Starting address of actual */ +/* queue area */ +/* queue_size Total size of queue */ +/* message_type Type of message supported by */ +/* the queue (fixed/variable) */ +/* message_size Size of message. Variable */ +/* message-length queues, this*/ +/* represents the maximum size*/ +/* suspend_type Suspension type */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_QUEUE Invalid queue pointer */ +/* NU_INVALID_MEMORY Invalid queue starting addr */ +/* NU_INVALID_SIZE Invalid queue size and/or */ +/* size of message */ +/* NU_INVALID_MESSAGE Invalid message type */ +/* NU_INVALID_SUSPEND Invalid suspend type */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS QUCE_Create_Queue(NU_QUEUE *queue_ptr, CHAR *name, + VOID *start_address, UNSIGNED queue_size, + OPTION message_type, UNSIGNED message_size, + OPTION suspend_type) +{ + +QU_QCB *queue; +STATUS status; +INT overhead; + + + /* Move input queue pointer into internal pointer. */ + queue = (QU_QCB *) queue_ptr; + + /* Determine if queue supports variable length messages. If so, an + additional word of overhead is required. */ + if (message_type == NU_VARIABLE_SIZE) + + /* Variable-size queues require an additional word of overhead. */ + overhead = 1; + else + + /* Fixed-size message queues require no additional overhead. */ + overhead = 0; + + /* Determine if there is an error with the queue pointer. */ + if ((queue == NU_NULL) || (queue -> qu_id == QU_QUEUE_ID)) + + /* Indicate that the queue pointer is invalid. */ + status = NU_INVALID_QUEUE; + + else if (start_address == NU_NULL) + + /* Indicate that the starting address of the queue is invalid. */ + status = NU_INVALID_MEMORY; + + else if ((queue_size == 0) || (message_size == 0) || + ((message_size+overhead) > queue_size)) + + /* Indicate that one or both of the size parameters are invalid. */ + status = NU_INVALID_SIZE; + + else if ((message_type != NU_FIXED_SIZE) && + (message_type != NU_VARIABLE_SIZE)) + + /* Indicate that the message type is invalid. */ + status = NU_INVALID_MESSAGE; + + else if ((suspend_type != NU_FIFO) && (suspend_type != NU_PRIORITY)) + + /* Indicate that the suspend type is invalid. */ + status = NU_INVALID_SUSPEND; + + else + + /* All the parameters are okay, call the actual function to create + a queue. */ + status = QUC_Create_Queue(queue_ptr, name, start_address, queue_size, + message_type, message_size, suspend_type); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* QUCE_Delete_Queue */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameter supplied */ +/* to the queue delete function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* QUC_Delete_Queue Actual delete queue function */ +/* */ +/* INPUTS */ +/* */ +/* queue_ptr Queue control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_QUEUE Invalid queue pointer */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS QUCE_Delete_Queue(NU_QUEUE *queue_ptr) +{ + +QU_QCB *queue; +STATUS status; + + + /* Move input queue pointer into internal pointer. */ + queue = (QU_QCB *) queue_ptr; + + /* Determine if there is an error with the queue pointer. */ + if (queue == NU_NULL) + + /* Indicate that the queue pointer is invalid. */ + status = NU_INVALID_QUEUE; + + else if (queue -> qu_id != QU_QUEUE_ID) + + /* Indicate that the queue pointer is invalid. */ + status = NU_INVALID_QUEUE; + + else + + /* All the parameters are okay, call the actual function to delete + a queue. */ + status = QUC_Delete_Queue(queue_ptr); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* QUCE_Send_To_Queue */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the send message to queue function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* QUC_Send_To_Queue Actual send queue message */ +/* function */ +/* TCCE_Suspend_Error Check suspend validity */ +/* */ +/* INPUTS */ +/* */ +/* queue_ptr Queue control block pointer */ +/* message Pointer to message to send */ +/* size Size of message to send */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_QUEUE Invalid queue pointer */ +/* NU_INVALID_POINTER Invalid message pointer */ +/* NU_INVALID_SIZE Invalid message size */ +/* NU_INVALID_SUSPEND Invalid suspend request */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 06-04-1998 Corrected SPR493 */ +/* */ +/*************************************************************************/ +STATUS QUCE_Send_To_Queue(NU_QUEUE *queue_ptr, VOID *message, UNSIGNED size, + UNSIGNED suspend) +{ + +QU_QCB *queue; +STATUS status; + + + /* Move input queue pointer into internal pointer. */ + queue = (QU_QCB *) queue_ptr; + + /* Determine if there is an error with the queue pointer. */ + if (queue == NU_NULL) + + /* Indicate that the queue pointer is invalid. */ + status = NU_INVALID_QUEUE; + + else if (queue -> qu_id != QU_QUEUE_ID) + + /* Indicate that the queue pointer is invalid. */ + status = NU_INVALID_QUEUE; + + else if (message == NU_NULL) + + /* Indicate that the pointer to the message is invalid. */ + status = NU_INVALID_POINTER; + + else if (size == 0) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + else if ((queue -> qu_fixed_size) && (size != queue -> qu_message_size)) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + else if ((!queue -> qu_fixed_size) && (size > queue -> qu_message_size)) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + else if ((suspend) && (TCCE_Suspend_Error())) + + /* Indicate that the suspension is only allowed from a task thread. */ + status = NU_INVALID_SUSPEND; + + else + + /* All the parameters are okay, call the actual function to send + a message to a queue. */ + status = QUC_Send_To_Queue(queue_ptr, message, size, suspend); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* QUCE_Receive_From_Queue */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the receive message from queue function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* QUC_Receive_From_Queue Actual receive message from */ +/* queue */ +/* TCCE_Suspend_Error Check suspend validity */ +/* */ +/* INPUTS */ +/* */ +/* queue_ptr Queue control block pointer */ +/* message Pointer to message to send */ +/* size Size of the message */ +/* actual_size Size of message received */ +/* suspend Suspension option if empty */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_QUEUE Invalid queue pointer */ +/* NU_INVALID_POINTER Invalid message pointer */ +/* NU_INVALID_SIZE Invalid message size */ +/* NU_INVALID_SUSPEND Invalid suspend request */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 05-24-1996 Changed the variable queue check */ +/* from "message size not equal */ +/* to pipe message size" to */ +/* "message size greater than */ +/* pipe message size" (SPR142). */ +/* */ +/*************************************************************************/ +STATUS QUCE_Receive_From_Queue(NU_QUEUE *queue_ptr, VOID *message, + UNSIGNED size, UNSIGNED *actual_size, UNSIGNED suspend) +{ + +QU_QCB *queue; +STATUS status; + + + /* Move input queue pointer into internal pointer. */ + queue = (QU_QCB *) queue_ptr; + + /* Determine if there is an error with the queue pointer. */ + if (queue == NU_NULL) + + /* Indicate that the queue pointer is invalid. */ + status = NU_INVALID_QUEUE; + + else if (queue -> qu_id != QU_QUEUE_ID) + + /* Indicate that the queue pointer is invalid. */ + status = NU_INVALID_QUEUE; + + else if (message == NU_NULL) + + /* Indicate that the pointer to the message is invalid. */ + status = NU_INVALID_POINTER; + + else if (size == 0) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + else if ((queue -> qu_fixed_size) && (size != queue -> qu_message_size)) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + else if ((!queue -> qu_fixed_size) && (size > queue -> qu_message_size)) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + else if ((suspend) && (TCCE_Suspend_Error())) + + /* Indicate that the suspension is only allowed from a task thread. */ + status = NU_INVALID_SUSPEND; + + else + + /* All the parameters are okay, call the actual function to receive + a message from a queue. */ + status = QUC_Receive_From_Queue(queue_ptr, message, size, + actual_size, suspend); + + /* Return completion status. */ + return(status); +} + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/qud.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,87 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* qud.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* QU - Queue Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains global data structures for use within the */ +/* queue management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* QUD_Created_Queue_List Pointer to the linked-list */ +/* of created queues */ +/* QUD_Total_Queues Total number of created */ +/* queues */ +/* QUD_List_Protect Queue list protection */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* qu_defs.h Queue Management constants */ +/* tc_defs.h Thread Control constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified copyright, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + +#include "qu_defs.h" /* Queue constants */ + + +/* QUD_Created_Queues_List is the head pointer of the linked list of + created queues. If the list is NU_NULL, there are no queues + created. */ + +CS_NODE *QUD_Created_Queues_List; + + +/* QUD_Total_Queues contains the number of currently created + queues. */ + +UNSIGNED QUD_Total_Queues; + + +/* QUD_List_Protect is a list protection structure used to block any other + thread from access to the created queue list. */ + +TC_PROTECT QUD_List_Protect; + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/quf.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,391 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* quf.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* QU - Queue Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains routines to obtain facts about the Queue */ +/* management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* QUF_Established_Queues Number of created queues */ +/* QUF_Queue_Information Retrieve queue information */ +/* QUF_Queue_Pointers Build queue pointer list */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* qu_extr.h Queue functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Initial version of queue fact */ +/* service file, version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 11-18-1996 Protected Informational service */ +/* from NULL Control Block pointers */ +/* creating 1.2a. (SPR220) */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "qu_extr.h" /* Queue functions */ +#include "hi_extr.h" /* History functions */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *QUD_Created_Queues_List; +extern UNSIGNED QUD_Total_Queues; +extern TC_PROTECT QUD_List_Protect; + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* QUF_Established_Queues */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the current number of established */ +/* queues. Queues previously deleted are no longer considered */ +/* established. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* QUD_Total_Queues Number of established */ +/* queues */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED QUF_Established_Queues(VOID) +{ + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Return the number of established queues. */ + return(QUD_Total_Queues); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* QUF_Queue_Pointers */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function builds a list of queue pointers, starting at the */ +/* specified location. The number of queue pointers placed in the */ +/* list is equivalent to the total number of queues or the maximum */ +/* number of pointers specified in the call. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect created list */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* pointer_list Pointer to the list area */ +/* maximum_pointers Maximum number of pointers */ +/* */ +/* OUTPUTS */ +/* */ +/* pointers Number of queue pointers */ +/* placed in the list */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected pointer retrieval */ +/* loop, resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED QUF_Queue_Pointers(NU_QUEUE **pointer_list,UNSIGNED maximum_pointers) +{ +CS_NODE *node_ptr; /* Pointer to each QCB */ +UNSIGNED pointers; /* Number of pointers in list*/ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Initialize the number of pointers returned. */ + pointers = 0; + + /* Protect against access to the list of created queues. */ + TCT_Protect(&QUD_List_Protect); + + /* Loop until all queue pointers are in the list or until the maximum + list size is reached. */ + node_ptr = QUD_Created_Queues_List; + while ((node_ptr) && (pointers < maximum_pointers)) + { + + /* Place the node into the destination list. */ + *pointer_list++ = (NU_QUEUE *) node_ptr; + + /* Increment the pointers variable. */ + pointers++; + + /* Position the node pointer to the next node. */ + node_ptr = node_ptr -> cs_next; + + /* Determine if the pointer is at the head of the list. */ + if (node_ptr == QUD_Created_Queues_List) + + /* The list search is complete. */ + node_ptr = NU_NULL; + } + + /* Release protection against access to the list of created queues. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the number of pointers in the list. */ + return(pointers); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* QUF_Queue_Information */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns information about the specified queue. */ +/* However, if the supplied queue pointer is invalid, the */ +/* function simply returns an error status. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_System_Protect Protect queue */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* queue_ptr Pointer to the queue */ +/* name Destination for the name */ +/* start_address Destination for the start */ +/* address of the queue */ +/* queue_size Destination for queue size */ +/* available Destination for available */ +/* room in queue */ +/* messages Destination for number of */ +/* messages queued */ +/* message_type Destination for message type */ +/* message_size Destination for message size */ +/* suspend_type Destination for suspension */ +/* type */ +/* tasks_waiting Destination for the tasks */ +/* waiting count */ +/* first_task Destination for the pointer */ +/* to the first task waiting */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If a valid queue pointer */ +/* is supplied */ +/* NU_INVALID_QUEUE If queue pointer invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* changed protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 11-18-1996 Corrected SPR220. */ +/* */ +/*************************************************************************/ +STATUS QUF_Queue_Information(NU_QUEUE *queue_ptr, CHAR *name, + VOID **start_address, UNSIGNED *queue_size, + UNSIGNED *available, UNSIGNED *messages, + OPTION *message_type, UNSIGNED *message_size, + OPTION *suspend_type, UNSIGNED *tasks_waiting, + NU_TASK **first_task) +{ + +QU_QCB *queue; /* Queue control block ptr */ +INT i; /* Working integer variable */ +STATUS completion; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input queue pointer into internal pointer. */ + queue = (QU_QCB *) queue_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Determine if this queue id is valid. */ + if ((queue != NU_NULL) && (queue -> qu_id == QU_QUEUE_ID)) + { + + /* Setup protection of the queue. */ + TCT_System_Protect(); + + /* The queue pointer is valid. Reflect this in the completion + status and fill in the actual information. */ + completion = NU_SUCCESS; + + /* Copy the queue's name. */ + for (i = 0; i < NU_MAX_NAME; i++) + *name++ = queue -> qu_name[i]; + + /* Determine the suspension type. */ + if (queue -> qu_fifo_suspend) + *suspend_type = NU_FIFO; + else + *suspend_type = NU_PRIORITY; + + /* Determine the message type. */ + if (queue -> qu_fixed_size) + *message_type = NU_FIXED_SIZE; + else + *message_type = NU_VARIABLE_SIZE; + + /* Get various information about the queue. */ + *start_address = (UNSIGNED *) queue -> qu_start; + *queue_size = queue -> qu_queue_size; + *available = queue -> qu_available; + *messages = queue -> qu_messages; + *message_size = queue -> qu_message_size; + + /* Retrieve the number of tasks waiting and the pointer to the + first task waiting. */ + *tasks_waiting = queue -> qu_tasks_waiting; + if (queue -> qu_suspension_list) + + /* There is a task waiting. */ + *first_task = (NU_TASK *) + (queue -> qu_suspension_list) -> qu_suspended_task; + else + + /* There are no tasks waiting. */ + *first_task = NU_NULL; + + /* Release protection of the queue. */ + TCT_Unprotect(); + } + else + + /* Indicate that the queue pointer is invalid. */ + completion = NU_INVALID_QUEUE; + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the appropriate completion status. */ + return(completion); +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/qui.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,125 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* qui.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* QU - Queue Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the initialization routine for the queue */ +/* management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* QUI_Initialize Queue Management Initialize */ +/* */ +/* DEPENDENCIES */ +/* */ +/* qu_defs.h Queue component constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified copyright, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "qu_defs.h" /* Queue constants */ +#include "qu_extr.h" /* Queue interfaces */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *QUD_Created_Queues_List; +extern UNSIGNED QUD_Total_Queues; +extern TC_PROTECT QUD_List_Protect; + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* QUI_Initialize */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function initializes the data structures that control the */ +/* operation of the Queue component (QU). There are no queues */ +/* initially. This routine must be called from Supervisor mode in */ +/* Supervisor/User mode switching kernels. */ +/* */ +/* CALLED BY */ +/* */ +/* INC_Initialize System initialization */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* QUD_Created_Queues_List List of created queues */ +/* QUD_Total_Queues Number of created queues */ +/* QUD_List_Protect Protection for queue list */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +VOID QUI_Initialize(VOID) +{ + + /* Initialize the created queue list to NU_NULL. */ + QUD_Created_Queues_List = NU_NULL; + + /* Initialize the total number of created queues to 0. */ + QUD_Total_Queues = 0; + + /* Initialize the list protection structure. */ + QUD_List_Protect.tc_tcb_pointer = NU_NULL; +} + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/qus.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,1062 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* qus.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* QU - Queue Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains supplemental routines for the Queue */ +/* Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* QUS_Reset_Queue Reset a queue */ +/* QUS_Send_To_Front_Of_Queue Send message to queue's front*/ +/* QUS_Broadcast_To_Queue Broadcast a message to queue */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* qu_extr.h Queue functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Created initial version 1.1 from */ +/* routines originally in core */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 02-04-1998 Corrected SPR434 resulting in */ +/* version 1.2a. */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "qu_extr.h" /* Queue functions */ +#include "hi_extr.h" /* History functions */ +#include "profiler.h" /* ProView interface */ + + +/* Define internal component function prototypes. */ + +VOID QUC_Cleanup(VOID *information); + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* QUS_Reset_Queue */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function resets the specified queue back to the original */ +/* state. Any messages in the queue are discarded. Also, any */ +/* tasks currently suspended on the queue are resumed with the */ +/* reset status. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* QUSE_Reset_Queue Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_System_Protect Protect queue data structures*/ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* queue_ptr Queue control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, fixed read and write */ +/* pointers to both point at the */ +/* start, resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 02-04-1998 Corrected SPR434. */ +/* */ +/*************************************************************************/ +STATUS QUS_Reset_Queue(NU_QUEUE *queue_ptr) +{ + +R1 QU_QCB *queue; /* Queue control block ptr */ +QU_SUSPEND *suspend_ptr; /* Suspend block pointer */ +QU_SUSPEND *next_ptr; /* Next suspend block pointer*/ +STATUS preempt; /* Status for resume call */ +NU_SUPERV_USER_VARIABLES + + /* Move input queue pointer into internal pointer. */ + queue = (QU_QCB *) queue_ptr; + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_RESET_QUEUE_ID, (UNSIGNED) queue, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Protect against access to the queue. */ + TCT_System_Protect(); + + /* Pickup the suspended task suspension list. */ + suspend_ptr = queue -> qu_suspension_list; + + /* Walk the chain task(s) currently suspended on the queue. */ + preempt = 0; + while (suspend_ptr) + { + + /* Resume the suspended task. Insure that the status returned is + NU_QUEUE_RESET. */ + suspend_ptr -> qu_return_status = NU_QUEUE_RESET; + + /* Point to the next suspend structure in the link. */ + next_ptr = (QU_SUSPEND *) (suspend_ptr -> qu_suspend_link.cs_next); + + /* Resume the specified task. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> qu_suspended_task, + NU_QUEUE_SUSPEND); + + /* Determine if the next is the same as the head pointer. */ + if (next_ptr == queue -> qu_suspension_list) + + /* Clear the suspension pointer to signal the end of the list + traversal. */ + suspend_ptr = NU_NULL; + else + + /* Position the suspend pointer to the next suspend block. */ + suspend_ptr = next_ptr; + } + + /* Pickup the urgent message suspension list. */ + suspend_ptr = queue -> qu_urgent_list; + + /* Walk the chain task(s) currently suspended on the queue. */ + while (suspend_ptr) + { + + /* Resume the suspended task. Insure that the status returned is + NU_QUEUE_RESET. */ + suspend_ptr -> qu_return_status = NU_QUEUE_RESET; + + /* Point to the next suspend structure in the link. */ + next_ptr = (QU_SUSPEND *) (suspend_ptr -> qu_suspend_link.cs_next); + + /* Resume the specified task. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> qu_suspended_task, + NU_QUEUE_SUSPEND); + + /* Determine if the next is the same as the head pointer. */ + if (next_ptr == queue -> qu_urgent_list) + + /* Clear the suspension pointer to signal the end of the list + traversal. */ + suspend_ptr = NU_NULL; + else + + /* Position suspend pointer to the next suspend block. */ + suspend_ptr = next_ptr; + } + + /* Initialize various elements of the queue. */ + queue -> qu_available = queue -> qu_end - queue -> qu_start; + queue -> qu_messages = 0; + queue -> qu_read = queue -> qu_start; + queue -> qu_write = queue -> qu_start; + queue -> qu_tasks_waiting = 0; + queue -> qu_suspension_list = NU_NULL; + queue -> qu_urgent_list = NU_NULL; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpQueue(RT_PROF_RESET_QUEUE,queue,RT_PROF_OK); +#endif + + /* Determine if preemption needs to occur. */ + if (preempt) + + /* Transfer control to system to facilitate preemption. */ + TCT_Control_To_System(); + + /* Release protection against access to the queue. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return a successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* QUS_Send_To_Front_Of_Queue */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sends a message to the front of the specified */ +/* message queue. The message length is determined by the caller. */ +/* If there are any tasks suspended on the queue for a message, the */ +/* message is copied into the message area of the first waiting */ +/* task and that task is resumed. If there is enough room in the */ +/* queue, the message is copied in front of all other messages. */ +/* If there is not enough room in the queue, suspension of the */ +/* caller is possible. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* QUSE_Send_To_Front_Of_Queue Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Place on suspend list */ +/* CSC_Remove_From_List Remove from suspend list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* TCC_Suspend_Task Suspend calling task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Current_Thread Pickup current thread pointer*/ +/* TCT_System_Protect Protect queue */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* queue_ptr Queue control block pointer */ +/* message Pointer to message to send */ +/* size Size of message to send */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If service is successful */ +/* NU_QUEUE_FULL If queue is currently full */ +/* NU_TIMEOUT If timeout on service expires*/ +/* NU_QUEUE_DELETED If queue was deleted during */ +/* suspension */ +/* NU_QUEUE_RESET If queue was reset during */ +/* suspension */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, optimized copy loop, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS QUS_Send_To_Front_Of_Queue(NU_QUEUE *queue_ptr, VOID *message, + UNSIGNED size, UNSIGNED suspend) +{ + +R1 QU_QCB *queue; /* Queue control block ptr */ +QU_SUSPEND suspend_block; /* Allocate suspension block */ +QU_SUSPEND *suspend_ptr; /* Pointer to suspend block */ +R3 UNSIGNED_PTR source; /* Pointer to source */ +R4 UNSIGNED_PTR destination; /* Pointer to destination */ +UNSIGNED copy_size; /* Partial copy size */ +R2 INT i; /* Working counter */ +TC_TCB *task; /* Task pointer */ +STATUS preempt; /* Preempt flag */ +STATUS status; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input queue pointer into internal pointer. */ + queue = (QU_QCB *) queue_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_SEND_TO_FRONT_OF_QUEUE_ID, (UNSIGNED) queue, + (UNSIGNED) message, (UNSIGNED) size); + +#endif + + /* Initialize the status as successful. */ + status = NU_SUCCESS; + + /* Protect against simultaneous access to the queue. */ + TCT_System_Protect(); + + /* Determine if an extra word of overhead needs to be added to the + calculation. */ + if (queue -> qu_fixed_size) + + /* No overhead. */ + i = 0; + else + { + /* Variable messages have one additional word of overhead. */ + i = 1; + + /* Make special check to see if a suspension needs to be + forced for a variable length message. */ + if ((queue -> qu_suspension_list) && (queue -> qu_messages)) + { + + /* Pickup task control block pointer. */ + task = (TC_TCB *) TCT_Current_Thread(); + + /* Now we know that there are other task(s) are suspended trying + to send a variable length message. Determine whether or not + a suspension should be forced. */ + if ((queue -> qu_fifo_suspend) || + (suspend == NU_NO_SUSPEND) || + ((queue -> qu_suspension_list) -> qu_suspend_link.cs_priority <= + TCC_Task_Priority(task))) + + /* Bump the computed size to avoid placing the new variable + length message ahead of the suspended tasks. */ + i = (INT) queue -> qu_available; + } + } + + /* Determine if there is enough room in the queue for the message. */ + if (queue -> qu_available < (size + i)) + { + + /* Queue does not have room for the message. Determine if + suspension is required. */ + if (suspend) + { + + /* Suspension is requested. */ + + /* Increment the number of tasks waiting. */ + queue -> qu_tasks_waiting++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpQueue(RT_PROF_SEND_TO_FRONT_OF_QUEUE,queue,RT_PROF_WAIT); +#endif + + /* Setup the suspend block and suspend the calling task. */ + suspend_ptr = &suspend_block; + suspend_ptr -> qu_queue = queue; + suspend_ptr -> qu_suspend_link.cs_next = NU_NULL; + suspend_ptr -> qu_suspend_link.cs_previous = NU_NULL; + suspend_ptr -> qu_message_area = (UNSIGNED_PTR) message; + suspend_ptr -> qu_message_size = size; + task = (TC_TCB *) TCT_Current_Thread(); + suspend_ptr -> qu_suspended_task = task; + + /* Place the task on the urgent message suspension list. */ + CSC_Place_On_List((CS_NODE **) &(queue -> qu_urgent_list), + &(suspend_ptr -> qu_suspend_link)); + + /* Move the head pointer of the list to make this suspension the + first in the list. */ + queue -> qu_urgent_list = (QU_SUSPEND *) + (queue -> qu_urgent_list) -> qu_suspend_link.cs_previous; + + /* Finally, suspend the calling task. Note that the suspension call + automatically clears the protection on the queue. */ + TCC_Suspend_Task((NU_TASK *) task, NU_QUEUE_SUSPEND, + QUC_Cleanup, suspend_ptr, suspend); + + /* Pickup the return status. */ + status = suspend_ptr -> qu_return_status; + } + else + { + + /* Return a status of NU_QUEUE_FULL because there is no + room in the queue for the message. */ + status = NU_QUEUE_FULL; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpQueue(RT_PROF_SEND_TO_FRONT_OF_QUEUE,queue,RT_PROF_FAIL); +#endif + } + } + else + { + + /* Determine if a task is waiting on an empty queue. */ + if ((queue -> qu_suspension_list) && (queue -> qu_messages == 0)) + { + + /* Task is waiting on queue for a message. */ + + /* Decrement the number of tasks waiting on queue. */ + queue -> qu_tasks_waiting--; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpQueue(RT_PROF_SEND_TO_FRONT_OF_QUEUE,queue,RT_PROF_OK); +#endif + + /* Remove the first suspended block from the list. */ + suspend_ptr = queue -> qu_suspension_list; + CSC_Remove_From_List((CS_NODE **) &(queue -> qu_suspension_list), + &(suspend_ptr -> qu_suspend_link)); + + /* Setup the source and destination pointers. */ + source = (UNSIGNED_PTR) message; + destination = suspend_ptr -> qu_message_area; + + /* Initialize the return status. */ + suspend_ptr -> qu_return_status = NU_SUCCESS; + + /* Loop to actually copy the message. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + + /* Return the size of the message copied. */ + suspend_ptr -> qu_actual_size = size; + + /* Wakeup the waiting task and check for preemption. */ + preempt = + TCC_Resume_Task((NU_TASK *) suspend_ptr -> qu_suspended_task, + NU_QUEUE_SUSPEND); + + /* Determine if preemption needs to take place. */ + if (preempt) + + /* Transfer control to the system if the resumed task function + detects a preemption condition. */ + TCT_Control_To_System(); + } + else + { + + /* There is enough room in the queue and no task is waiting. */ + + /* Setup the source pointer. */ + source = (UNSIGNED_PTR) message; + destination = queue -> qu_read; + + /* Process according to the type of message supported. */ + if (queue -> qu_fixed_size) + { + + /* Fixed-size message queue. */ + + /* Determine if the read pointer is at the top of the queue + area. */ + if (destination == queue -> qu_start) + + /* Prepare to place the message in the lower part + of the queue area. */ + destination = queue -> qu_end - size; + else + + /* Backup the length of a message from the current + read pointer. */ + destination = destination - size; + + /* Adjust the actual read pointer before the copy is done. */ + queue -> qu_read = destination; + + /* Copy the message into the queue area. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + else + { + + /* Variable-size message queue. */ + + /* Calculate the number of words remaining at the top of the + queue. */ + copy_size = destination - queue -> qu_start; + + /* Determine if part of the message needs to be placed at the + bottom of the queue area. */ + if (copy_size < (size + i)) + + /* Compute the starting location for the message. */ + destination = queue -> qu_end - ((size +i) - copy_size); + else + + /* Compute the starting location for the message. */ + destination = destination - (size + i); + + /* Adjust the actual queue read pointer also. */ + queue -> qu_read = destination; + + /* Place message size in first location. */ + *(destination++) = size; + + /* Check for a wrap-around condition on the queue. */ + if (destination >= queue -> qu_end) + + /* Wrap the write pointer back to the top of the queue + area. */ + destination = queue -> qu_start; + + /* Decrement the number of words remaining by 1 for this + extra word of overhead. */ + queue -> qu_available--; + + /* Calculate the number of words remaining from the + destination pointer to the bottom of the queue. */ + copy_size = queue -> qu_end - destination; + + /* Determine if the message needs to be wrapped around the + edge of the queue area. */ + if (copy_size >= size) + { + + /* Copy the whole message at once. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + else + { + + /* Copy the first half of the message. */ + i = (INT) copy_size; + do + { + *(destination) = *(source++); + if ((--i) == 0) + break; + destination++; + } while (1); + + /* Copy the second half of the message. */ + destination = queue -> qu_start; + i = (INT) (size - copy_size); + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + } + + /* Decrement the number of available words. */ + queue -> qu_available = queue -> qu_available - size; + + /* Increment the number of messages in the queue. */ + queue -> qu_messages++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpQueue(RT_PROF_SEND_TO_FRONT_OF_QUEUE,queue,RT_PROF_OK); +#endif + + } + } + + /* Release protection against access to the queue. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* QUS_Broadcast_To_Queue */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sends a message to all tasks waiting for a message */ +/* from the specified queue. If there are no tasks waiting for a */ +/* message the service performs like a standard send request. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* QUSE_Broadcast_To_Queue Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Place on suspend list */ +/* CSC_Priority_Place_On_List Place on priority list */ +/* CSC_Remove_From_List Remove from suspend list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* TCC_Suspend_Task Suspend calling task */ +/* TCC_Task_Priority Pickup task's priority */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Current_Thread Pickup current thread pointer*/ +/* TCT_System_Protect Protect queue */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* queue_ptr Queue control block pointer */ +/* message Pointer to message to send */ +/* size Size of message to send */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If service is successful */ +/* NU_QUEUE_FULL If queue is currently full */ +/* NU_TIMEOUT If timeout on service expires*/ +/* NU_QUEUE_DELETED If queue was deleted during */ +/* suspension */ +/* NU_QUEUE_RESET If queue was reset during */ +/* suspension */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, optimized copy loop, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS QUS_Broadcast_To_Queue(NU_QUEUE *queue_ptr, VOID *message, + UNSIGNED size, UNSIGNED suspend) +{ + +R1 QU_QCB *queue; /* Queue control block ptr */ +QU_SUSPEND suspend_block; /* Allocate suspension block */ +QU_SUSPEND *suspend_ptr; /* Pointer to suspend block */ +R3 UNSIGNED_PTR source; /* Pointer to source */ +R4 UNSIGNED_PTR destination; /* Pointer to destination */ +UNSIGNED copy_size; /* Partial copy size */ +R2 INT i; /* Working counter */ +TC_TCB *task; /* Task pointer */ +STATUS preempt; /* Preempt flag */ +STATUS status; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input queue pointer into internal pointer. */ + queue = (QU_QCB *) queue_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_BROADCAST_TO_QUEUE_ID, (UNSIGNED) queue, + (UNSIGNED) message, (UNSIGNED) size); + +#endif + + /* Initialize the status as successful. */ + status = NU_SUCCESS; + + /* Protect against simultaneous access to the queue. */ + TCT_System_Protect(); + + /* Determine if an extra word of overhead needs to be added to the + calculation. */ + if (queue -> qu_fixed_size) + + /* No overhead. */ + i = 0; + else + { + /* Variable messages have one additional word of overhead. */ + i = 1; + + /* Make special check to see if a suspension needs to be + forced for a variable length message. */ + if ((queue -> qu_suspension_list) && (queue -> qu_messages)) + { + + /* Pickup task control block pointer. */ + task = (TC_TCB *) TCT_Current_Thread(); + + /* Now we know that there are other task(s) are suspended trying + to send a variable length message. Determine whether or not + a suspension should be forced. */ + if ((queue -> qu_fifo_suspend) || + (suspend == NU_NO_SUSPEND) || + ((queue -> qu_suspension_list) -> qu_suspend_link.cs_priority <= + TCC_Task_Priority(task))) + + /* Bump the computed size to avoid placing the new variable + length message ahead of the suspended tasks. */ + i = (INT) queue -> qu_available; + } + } + + /* Determine if there is enough room in the queue for the message. */ + if (queue -> qu_available < (size + i)) + { + + /* Queue does not have room for the message. Determine if + suspension is required. */ + if (suspend) + { + + /* Suspension is requested. */ + + /* Increment the number of tasks waiting. */ + queue -> qu_tasks_waiting++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpQueue(RT_PROF_BROADCAST_TO_QUEUE,queue,RT_PROF_WAIT); +#endif + + /* Setup the suspend block and suspend the calling task. */ + suspend_ptr = &suspend_block; + suspend_ptr -> qu_queue = queue; + suspend_ptr -> qu_suspend_link.cs_next = NU_NULL; + suspend_ptr -> qu_suspend_link.cs_previous = NU_NULL; + suspend_ptr -> qu_message_area = (UNSIGNED_PTR) message; + suspend_ptr -> qu_message_size = size; + task = (TC_TCB *) TCT_Current_Thread(); + suspend_ptr -> qu_suspended_task = task; + + /* Determine if priority or FIFO suspension is associated with the + queue. */ + if (queue -> qu_fifo_suspend) + { + + /* FIFO suspension is required. Link the suspend block into + the list of suspended tasks on this queue. */ + CSC_Place_On_List((CS_NODE **) &(queue -> qu_suspension_list), + &(suspend_ptr -> qu_suspend_link)); + } + else + { + + /* Get the priority of the current thread so the suspend block + can be placed in the appropriate place. */ + suspend_ptr -> qu_suspend_link.cs_priority = + TCC_Task_Priority(task); + + CSC_Priority_Place_On_List((CS_NODE **) + &(queue -> qu_suspension_list), + &(suspend_ptr -> qu_suspend_link)); + } + + /* Finally, suspend the calling task. Note that the suspension call + automatically clears the protection on the queue. */ + TCC_Suspend_Task((NU_TASK *) task, NU_QUEUE_SUSPEND, + QUC_Cleanup, suspend_ptr, suspend); + + /* Pickup the return status. */ + status = suspend_ptr -> qu_return_status; + } + else + { + + /* Return a status of NU_QUEUE_FULL because there is no + room in the queue for the message. */ + status = NU_QUEUE_FULL; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpQueue(RT_PROF_BROADCAST_TO_QUEUE,queue,RT_PROF_FAIL); +#endif + + } + } + else + { + + /* Determine if a task is waiting on an empty queue. */ + if ((queue -> qu_suspension_list) && (queue -> qu_messages == 0)) + { + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpQueue(RT_PROF_BROADCAST_TO_QUEUE,queue,RT_PROF_OK); +#endif + + /* Yes, one or more tasks are waiting for a message from this + queue. */ + preempt = 0; + do + { + + /* Decrement the number of tasks waiting on queue. */ + queue -> qu_tasks_waiting--; + + /* Remove the first suspended block from the list. */ + suspend_ptr = queue -> qu_suspension_list; + CSC_Remove_From_List((CS_NODE **) + &(queue -> qu_suspension_list), + &(suspend_ptr -> qu_suspend_link)); + + /* Setup the source and destination pointers. */ + source = (UNSIGNED_PTR) message; + destination = suspend_ptr -> qu_message_area; + + /* Initialize the return status. */ + suspend_ptr -> qu_return_status = NU_SUCCESS; + + /* Loop to actually copy the message. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + + /* Return the size of the message copied. */ + suspend_ptr -> qu_actual_size = size; + + /* Wakeup the waiting task and check for preemption. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> qu_suspended_task, + NU_QUEUE_SUSPEND); + + /* Move the suspend pointer to the next node, which is now + at the head of the list. */ + suspend_ptr = queue -> qu_suspension_list; + } while (suspend_ptr); + + /* Determine if preemption needs to take place. */ + if (preempt) + + /* Transfer control to the system if the resumed task function + detects a preemption condition. */ + TCT_Control_To_System(); + } + else + { + + /* There is enough room in the queue and no task is waiting. */ + + /* Setup the source pointer. */ + source = (UNSIGNED_PTR) message; + destination = queue -> qu_write; + + /* Process according to the type of message supported. */ + if (queue -> qu_fixed_size) + { + + /* Fixed-size messages are supported by this queue. */ + + /* Loop to copy the message into the queue area. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + else + { + + /* Variable-size messages are supported. Processing must + check for queue wrap-around conditions. */ + + /* Place message size in first location. */ + *(destination++) = size; + + /* Check for a wrap-around condition on the queue. */ + if (destination >= queue -> qu_end) + + /* Wrap the write pointer back to the top of the queue + area. */ + destination = queue -> qu_start; + + /* Decrement the number of words remaining by 1 for this + extra word of overhead. */ + queue -> qu_available--; + + /* Calculate the number of words remaining from the write + pointer to the bottom of the queue. */ + copy_size = queue -> qu_end - destination; + + /* Determine if the message needs to be wrapped around the + edge of the queue area. */ + if (copy_size >= size) + { + + /* Copy the whole message at once. */ + i = (INT) size; + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while(1); + } + else + { + + /* Copy the first half of the message. */ + i = (INT) copy_size; + do + { + *(destination) = *(source++); + if ((--i) == 0) + break; + destination++; + } while (1); + + /* Copy the second half of the message. */ + destination = queue -> qu_start; + i = (INT) (size - copy_size); + do + { + *(destination++) = *(source); + if ((--i) == 0) + break; + source++; + } while (1); + } + } + + /* Check again for wrap-around condition on the write pointer. */ + if (destination >= queue -> qu_end) + + /* Move the write pointer to the top of the queue area. */ + queue -> qu_write = queue -> qu_start; + else + + /* Simply copy the last position of the destination pointer + into the write pointer. */ + queue -> qu_write = destination; + + /* Decrement the number of available words. */ + queue -> qu_available = queue -> qu_available - size; + + /* Increment the number of messages in the queue. */ + queue -> qu_messages++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpQueue(RT_PROF_BROADCAST_TO_QUEUE,queue,RT_PROF_OK); +#endif + } + } + + /* Release protection against access to the queue. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(status); +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/quse.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,350 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* quse.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* QU - Queue Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains error checking routines for supplemental */ +/* functions in the Queue component. This permits easy removal of */ +/* error checking logic when it is not needed. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* QUSE_Reset_Queue Reset a queue */ +/* QUSE_Send_To_Front_Of_Queue Send message to queue's front*/ +/* QUSE_Broadcast_To_Queue Broadcast message to queue */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* qu_extr.h Queue functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Created initial version 1.1 from */ +/* routines originally in core */ +/* error checking file */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "qu_extr.h" /* Queue functions */ + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* QUSE_Reset_Queue */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameter supplied */ +/* to the queue reset function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* QUS_Reset_Queue Actual reset queue function */ +/* */ +/* INPUTS */ +/* */ +/* queue_ptr Queue control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_QUEUE Invalid queue pointer */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS QUSE_Reset_Queue(NU_QUEUE *queue_ptr) +{ + +QU_QCB *queue; +STATUS status; + + + /* Move input queue pointer into internal pointer. */ + queue = (QU_QCB *) queue_ptr; + + /* Determine if there is an error with the queue pointer. */ + if (queue == NU_NULL) + + /* Indicate that the queue pointer is invalid. */ + status = NU_INVALID_QUEUE; + + else if (queue -> qu_id != QU_QUEUE_ID) + + /* Indicate that the queue pointer is invalid. */ + status = NU_INVALID_QUEUE; + + else + + /* All the parameters are okay, call the actual function to reset + a queue. */ + status = QUS_Reset_Queue(queue_ptr); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* QUSE_Send_To_Front_Of_Queue */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the send message to front of queue function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* QUS_Send_To_Front_Of_Queue Actual send to front of */ +/* queue function */ +/* TCCE_Suspend_Error Check suspend validity */ +/* */ +/* INPUTS */ +/* */ +/* queue_ptr Queue control block pointer */ +/* message Pointer to message to send */ +/* size Size of message to send */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_QUEUE Invalid queue pointer */ +/* NU_INVALID_POINTER Invalid message pointer */ +/* NU_INVALID_SIZE Invalid message size */ +/* NU_INVALID_SUSPEND Invalid suspension request */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS QUSE_Send_To_Front_Of_Queue(NU_QUEUE *queue_ptr, VOID *message, + UNSIGNED size, UNSIGNED suspend) +{ + +QU_QCB *queue; +STATUS status; + + + /* Move input queue pointer into internal pointer. */ + queue = (QU_QCB *) queue_ptr; + + /* Determine if there is an error with the queue pointer. */ + if (queue == NU_NULL) + + /* Indicate that the queue pointer is invalid. */ + status = NU_INVALID_QUEUE; + + else if (queue -> qu_id != QU_QUEUE_ID) + + /* Indicate that the queue pointer is invalid. */ + status = NU_INVALID_QUEUE; + + else if (message == NU_NULL) + + /* Indicate that the pointer to the message is invalid. */ + status = NU_INVALID_POINTER; + + else if (size == 0) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + else if ((queue -> qu_fixed_size) && (size != queue -> qu_message_size)) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + else if ((!queue -> qu_fixed_size) && (size > queue -> qu_message_size)) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + else if ((suspend) && (TCCE_Suspend_Error())) + + /* Indicate that the suspension is only allowed from a task thread. */ + status = NU_INVALID_SUSPEND; + + else + + /* All the parameters are okay, call the actual function to send + a message to a queue. */ + status = QUS_Send_To_Front_Of_Queue(queue_ptr, message, size, + suspend); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* QUSE_Broadcast_To_Queue */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the broadcast message to queue function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* QUS_Broadcast_To_Queue Actual broadcast message */ +/* to queue function */ +/* TCCE_Suspend_Error Check suspend validity */ +/* */ +/* INPUTS */ +/* */ +/* queue_ptr Queue control block pointer */ +/* message Pointer to message to send */ +/* size Size of message to send */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_QUEUE Invalid queue pointer */ +/* NU_INVALID_POINTER Invalid message pointer */ +/* NU_INVALID_SIZE Invalid message size */ +/* NU_INVALID_SUSPEND Invalid suspend request */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-1-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS QUSE_Broadcast_To_Queue(NU_QUEUE *queue_ptr, VOID *message, + UNSIGNED size, UNSIGNED suspend) +{ + +QU_QCB *queue; +STATUS status; + + + /* Move input queue pointer into internal pointer. */ + queue = (QU_QCB *) queue_ptr; + + /* Determine if there is an error with the queue pointer. */ + if (queue == NU_NULL) + + /* Indicate that the queue pointer is invalid. */ + status = NU_INVALID_QUEUE; + + else if (queue -> qu_id != QU_QUEUE_ID) + + /* Indicate that the queue pointer is invalid. */ + status = NU_INVALID_QUEUE; + + else if (message == NU_NULL) + + /* Indicate that the pointer to the message is invalid. */ + status = NU_INVALID_POINTER; + + else if (size == 0) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + + else if ((queue -> qu_fixed_size) && (size != queue -> qu_message_size)) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + else if ((!queue -> qu_fixed_size) && (size > queue -> qu_message_size)) + + /* Indicate that the message size is invalid. */ + status = NU_INVALID_SIZE; + + else if ((suspend) && (TCCE_Suspend_Error())) + + /* Indicate that the suspension is only allowed from a task thread. */ + status = NU_INVALID_SUSPEND; + + else + + /* Broadcast a message to a queue. */ + status = QUS_Broadcast_To_Queue(queue_ptr, message, size, suspend); + + /* Return completion status. */ + return(status); +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/rlc.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,124 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* rlc.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* RL - Release Information */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the core routines for the Release Information */ +/* component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* RLC_Release_Information Return pointer to release */ +/* information string */ +/* */ +/* DEPENDENCIES */ +/* */ +/* nucleus.h System definitions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Replaced void with VOID, */ +/* added pointer variable, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + +#include "nucleus.h" /* System definitions */ + + +/* Define external inner-component global data references. */ + +extern const CHAR RLD_Release_String[]; + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* RLC_Release_Information */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns a pointer to the release information */ +/* string. The information string identifies the current version */ +/* of Nucleus PLUS. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* ptr Pointer to information string */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Replaced void with VOID, */ +/* added pointer variable, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +CHAR *RLC_Release_Information(VOID) +{ + +CHAR *ptr; + + /* Setup pointer to release string. */ + ptr = (CHAR *) &RLD_Release_String[0]; + + /* Return a pointer to the release information string. */ + return(ptr); +} + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/rld.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,80 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* rld.c Nucleus PLUS\ARM925\Code Composer 1.14.1 */ +/* */ +/* COMPONENT */ +/* */ +/* RL - Release Information */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains information about this release of Nucleus */ +/* PLUS. */ +/* */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* RLD_Release_String Release information string */ +/* RLD_Special_String Special Nucleus PLUS string */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* nucleus.h System definitions */ +/* */ +/* HISTORY */ +/* */ +/* NAME DATE REMARKS */ +/* */ +/* B. Ronquillo 08-28-2002 Released version 1.14.1 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + +#include "nucleus.h" /* System definitions */ + + +/* RLD_Release_String contains a string describing this release of Nucleus + PLUS. */ + +const CHAR RLD_Release_String[] = + "FreeNucleus demo release - based on Nucleus PLUS v. 1.14.1"; + + +/* RLD_Special_String contains information about the origins of the Nucleus + PLUS system. */ + +const CHAR RLD_Special_String[] = + "G,M,D,GB,GL,AG,KL,CR,HR,NH,DL,BH,LP,AP,HA,ME,KC,KH,GF,RG,HS,DS,KY,BC,LC,TD"; + + + + + + + + + + + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/sm_defs.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,112 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* sm_defs.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* SM - Semaphore Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains data structure definitions and constants for */ +/* the Semaphore component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* SM_SCB Semaphore control block */ +/* SM_SUSPEND Semaphore suspension block */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_defs.h Common service definitions */ +/* tc_defs.h Thread Control definitions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* removed protection structure, */ +/* put padding into structure, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "cs_defs.h" /* Common service constants */ +#include "tc_defs.h" /* Thread control constants */ + + +/* Check to see if the file has been included already. */ + +#ifndef SM_DEFS +#define SM_DEFS + + +/* Define constants local to this component. */ + +#define SM_SEMAPHORE_ID 0x53454d41UL + + +/* Define the Semaphore Control Block data type. */ + +typedef struct SM_SCB_STRUCT +{ + CS_NODE sm_created; /* Node for linking to */ + /* created semaphore list */ + UNSIGNED sm_id; /* Internal SCB ID */ + CHAR sm_name[NU_MAX_NAME]; /* Semaphore name */ + UNSIGNED sm_semaphore_count; /* Counting semaphore */ + BOOLEAN sm_fifo_suspend; /* Suspension type flag */ +#if PAD_1 + DATA_ELEMENT sm_padding[PAD_1]; +#endif + UNSIGNED sm_tasks_waiting; /* Number of waiting tasks*/ + struct SM_SUSPEND_STRUCT + *sm_suspension_list; /* Suspension list */ +} SM_SCB; + + +/* Define the semaphore suspension structure. This structure is allocated + off of the caller's stack. */ + +typedef struct SM_SUSPEND_STRUCT +{ + CS_NODE sm_suspend_link; /* Link to suspend blocks */ + SM_SCB *sm_semaphore; /* Pointer to semaphore */ + TC_TCB *sm_suspended_task; /* Task suspended */ + STATUS sm_return_status; /* Return status */ +} SM_SUSPEND; + +#endif + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/sm_extr.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,118 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* sm_extr.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* SM - Semaphore Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains function prototypes of all functions */ +/* accessible to other components. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* sm_defs.h Semaphore Management constant*/ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* modified function prototypes, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "sm_defs.h" /* Include SM constants */ + + +/* Check to see if the file has been included already. */ + +#ifndef SM_EXTR +#define SM_EXTR + + +/* Initialization functions. */ + +VOID SMI_Initialize(VOID); + + +/* Error checking core functions. */ + +STATUS SMCE_Create_Semaphore(NU_SEMAPHORE *semaphore_ptr, CHAR *name, + UNSIGNED initial_count, OPTION suspend_type); +STATUS SMCE_Delete_Semaphore(NU_SEMAPHORE *semaphore_ptr); +STATUS SMCE_Obtain_Semaphore(NU_SEMAPHORE *semaphore_ptr, + UNSIGNED suspend); +STATUS SMCE_Release_Semaphore(NU_SEMAPHORE *semaphore_ptr); + + +/* Error checking supplemental functions. */ + +STATUS SMSE_Reset_Semaphore(NU_SEMAPHORE *semaphore_ptr, + UNSIGNED initial_count); + + +/* Core processing functions. */ + +STATUS SMC_Create_Semaphore(NU_SEMAPHORE *semaphore_ptr, CHAR *name, + UNSIGNED initial_count, OPTION suspend_type); +STATUS SMC_Delete_Semaphore(NU_SEMAPHORE *semaphore_ptr); +STATUS SMC_Obtain_Semaphore(NU_SEMAPHORE *semaphore_ptr, + UNSIGNED suspend); +STATUS SMC_Release_Semaphore(NU_SEMAPHORE *semaphore_ptr); + + +/* Supplemental processing functions. */ + +STATUS SMS_Reset_Semaphore(NU_SEMAPHORE *semaphore_ptr, + UNSIGNED initial_count); + + +/* Information retrieval functions. */ + +UNSIGNED SMF_Established_Semaphores(VOID); +STATUS SMF_Semaphore_Information(NU_SEMAPHORE *semaphore_ptr, + CHAR *name, UNSIGNED *current_count, OPTION *suspend_type, + UNSIGNED *tasks_waiting, NU_TASK **first_task); +UNSIGNED SMF_Semaphore_Pointers(NU_SEMAPHORE **pointer_list, + UNSIGNED maximum_pointers); +#endif + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/smc.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,811 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* smc.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* SM - Semaphore Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the core routines for the Semaphore Management*/ +/* component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* SMC_Create_Semaphore Create a semaphore */ +/* SMC_Delete_Semaphore Delete a semaphore */ +/* SMC_Obtain_Semaphore Obtain instance of semaphore */ +/* SMC_Release_Semaphore Release instance of semaphore*/ +/* SMC_Cleanup Cleanup on timeout or a */ +/* terminate condition */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* sm_extr.h Semaphore functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected pointer retrieval */ +/* loop, resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Moved non-core functions into */ +/* supplemental files, changed */ +/* function interfaces to match */ +/* those in prototype, added */ +/* register options, changed */ +/* protection logic to reduce */ +/* overhead, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "sm_extr.h" /* Semaphore functions */ +#include "hi_extr.h" /* History functions */ +#include "profiler.h" /* ProView interface */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *SMD_Created_Semaphores_List; +extern UNSIGNED SMD_Total_Semaphores; +extern TC_PROTECT SMD_List_Protect; + + +/* Define internal component function prototypes. */ + +VOID SMC_Cleanup(VOID *information); + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* SMC_Create_Semaphore */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function creates a semaphore and then places it on the list */ +/* of created semaphores. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* SMCE_Create_Semaphore Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Add node to linked-list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Data structure protect */ +/* TCT_Unprotect Un-protect data structure */ +/* */ +/* INPUTS */ +/* */ +/* semaphore_ptr Semaphore control block ptr */ +/* name Semaphore name */ +/* initial_count Initial semaphore instance */ +/* count */ +/* suspend_type Suspension type */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS SMC_Create_Semaphore(NU_SEMAPHORE *semaphore_ptr, CHAR *name, + UNSIGNED initial_count, OPTION suspend_type) +{ + +R1 SM_SCB *semaphore; /* Semaphore control blk ptr */ +INT i; /* Working index variable */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input semaphore pointer into internal pointer. */ + semaphore = (SM_SCB *) semaphore_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_CREATE_SEMAPHORE_ID, (UNSIGNED) semaphore, + (UNSIGNED) name, (UNSIGNED) initial_count); + +#endif + + /* First, clear the semaphore ID just in case it is an old Semaphore + Control Block. */ + semaphore -> sm_id = 0; + + /* Fill in the semaphore name. */ + for (i = 0; i < NU_MAX_NAME; i++) + semaphore -> sm_name[i] = name[i]; + + /* Setup the initial semaphore instance count. */ + semaphore -> sm_semaphore_count = initial_count; + + /* Setup the semaphore suspension type. */ + if (suspend_type == NU_FIFO) + + /* FIFO suspension is selected, setup the flag accordingly. */ + semaphore -> sm_fifo_suspend = NU_TRUE; + else + + /* Priority suspension is selected. */ + semaphore -> sm_fifo_suspend = NU_FALSE; + + /* Clear the suspension list pointer. */ + semaphore -> sm_suspension_list = NU_NULL; + + /* Clear the number of tasks waiting on the semaphore counter. */ + semaphore -> sm_tasks_waiting = 0; + + /* Initialize link pointers. */ + semaphore -> sm_created.cs_previous = NU_NULL; + semaphore -> sm_created.cs_next = NU_NULL; + + /* Protect against access to the list of created semaphores. */ + TCT_Protect(&SMD_List_Protect); + + /* At this point the semaphore is completely built. The ID can now be + set and it can be linked into the created semaphore list. */ + semaphore -> sm_id = SM_SEMAPHORE_ID; + + /* Link the semaphore into the list of created semaphores and increment the + total number of semaphores in the system. */ + CSC_Place_On_List(&SMD_Created_Semaphores_List,&(semaphore -> sm_created)); + SMD_Total_Semaphores++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpSema(RT_PROF_CREATE_SEMAPHORE,semaphore, RT_PROF_OK); +#endif + + /* Release protection against access to the list of created semaphores. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* SMC_Delete_Semaphore */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function deletes a semaphore and removes it from the list */ +/* of created semaphores. All tasks suspended on the semaphore are */ +/* resumed. Note that this function does not free the memory */ +/* associated with the semaphore control block. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* SMCE_Delete_Semaphore Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove node from list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Protect Protect created list */ +/* TCT_Set_Current_Protect Modify current protection */ +/* TCT_System_Protect Setup system protection */ +/* TCT_System_Unprotect Release system protection */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* semaphore_ptr Semaphore control block ptr */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS SMC_Delete_Semaphore(NU_SEMAPHORE *semaphore_ptr) +{ + +R1 SM_SCB *semaphore; /* Semaphore control blk ptr */ +SM_SUSPEND *suspend_ptr; /* Suspend block pointer */ +SM_SUSPEND *next_ptr; /* Next suspend block */ +STATUS preempt; /* Status for resume call */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input semaphore pointer into internal pointer. */ + semaphore = (SM_SCB *) semaphore_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_DELETE_SEMAPHORE_ID, (UNSIGNED) semaphore, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Protect against access to the semaphore. */ + TCT_System_Protect(); + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpSema(RT_PROF_DELETE_SEMAPHORE,semaphore, RT_PROF_OK); +#endif + + /* Clear the semaphore ID. */ + semaphore -> sm_id = 0; + + /* Release protection. */ + TCT_Unprotect(); + + /* Protect against access to the list of created semaphores. */ + TCT_Protect(&SMD_List_Protect); + + /* Remove the semaphore from the list of created semaphores. */ + CSC_Remove_From_List(&SMD_Created_Semaphores_List, + &(semaphore -> sm_created)); + + /* Decrement the total number of created semaphores. */ + SMD_Total_Semaphores--; + + /* Pickup the suspended task pointer list. */ + suspend_ptr = semaphore -> sm_suspension_list; + + /* Walk the chain task(s) currently suspended on the semaphore. */ + preempt = 0; + while (suspend_ptr) + { + + /* Protect against system access. */ + TCT_System_Protect(); + + /* Resume the suspended task. Insure that the status returned is + NU_SEMAPHORE_DELETED. */ + suspend_ptr -> sm_return_status = NU_SEMAPHORE_DELETED; + + /* Point to the next suspend structure in the link. */ + next_ptr = (SM_SUSPEND *) (suspend_ptr -> sm_suspend_link.cs_next); + + /* Resume the specified task. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> sm_suspended_task, + NU_SEMAPHORE_SUSPEND); + + /* Determine if the next is the same as the current pointer. */ + if (next_ptr == semaphore -> sm_suspension_list) + + /* Clear the suspension pointer to signal the end of the list + traversal. */ + suspend_ptr = NU_NULL; + else + + /* Move the next pointer into the suspend block pointer. */ + suspend_ptr = next_ptr; + + /* Modify current protection. */ + TCT_Set_Current_Protect(&SMD_List_Protect); + + /* Clear the system protection. */ + TCT_System_Unprotect(); + } + + /* Determine if preemption needs to occur. */ + if (preempt) + + /* Transfer control to system to facilitate preemption. */ + TCT_Control_To_System(); + + /* Release protection against access to the list of created semaphores. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return a successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* SMC_Obtain_Semaphore */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function obtains an instance of the semaphore. An instance */ +/* corresponds to decrementing the counter by 1. If the counter is */ +/* greater than zero at the time of this call, this function can be */ +/* completed immediately. Otherwise, suspension is possible. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* SMCE_Obtain_Semaphore Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Place on suspend list */ +/* CSC_Priority_Place_On_List Place on priority list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Suspend_Task Suspend calling task */ +/* TCC_Task_Priority Obtain task's priority */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Current_Thread Pickup current thread pointer*/ +/* TCT_System_Protect Protect semaphore */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* semaphore_ptr Semaphore control block ptr */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If service is successful */ +/* NU_UNAVAILABLE If an instance of the */ +/* semaphore is not available */ +/* NU_TIMEOUT If timeout on service */ +/* NU_SEMAPHORE_DELETED If semaphore deleted during */ +/* suspension */ +/* NU_SEMAPHORE_RESET If semaphore reset during */ +/* suspension */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS SMC_Obtain_Semaphore(NU_SEMAPHORE *semaphore_ptr, UNSIGNED suspend) +{ + +R1 SM_SCB *semaphore; /* Semaphore control blk ptr */ +R2 SM_SUSPEND *suspend_ptr; /* Suspend block pointer */ +SM_SUSPEND suspend_block; /* Allocate suspension block */ +TC_TCB *task; /* Task pointer */ +STATUS status; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input semaphore pointer into internal pointer. */ + semaphore = (SM_SCB *) semaphore_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_OBTAIN_SEMAPHORE_ID, (UNSIGNED) semaphore, + (UNSIGNED) suspend, (UNSIGNED) 0); + +#endif + + /* Initialize the status as successful. */ + status = NU_SUCCESS; + + /* Protect against simultaneous access to the semaphore. */ + TCT_System_Protect(); + + /* Determine if the semaphore has an instance (can be decremented). */ + if (semaphore -> sm_semaphore_count) + { + + /* Semaphore available. Decrement and return to the caller. */ + semaphore -> sm_semaphore_count--; +#ifdef INCLUDE_PROVIEW + _RTProf_DumpSema(RT_PROF_OBTAIN_SEMAPHORE,semaphore, RT_PROF_OK); +#endif + + } + else + { + + /* Semaphore is not available. Determine if suspension is required. */ + if (suspend) + { + + /* Suspension is selected. */ + + /* Increment the number of tasks waiting. */ + semaphore -> sm_tasks_waiting++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpSema(RT_PROF_OBTAIN_SEMAPHORE,semaphore , RT_PROF_WAIT); +#endif + + /* Setup the suspend block and suspend the calling task. */ + suspend_ptr = &suspend_block; + suspend_ptr -> sm_semaphore = semaphore; + suspend_ptr -> sm_suspend_link.cs_next = NU_NULL; + suspend_ptr -> sm_suspend_link.cs_previous = NU_NULL; + task = (TC_TCB *) TCT_Current_Thread(); + suspend_ptr -> sm_suspended_task = task; + + /* Determine if priority or FIFO suspension is associated with the + semaphore. */ + if (semaphore -> sm_fifo_suspend) + { + + /* FIFO suspension is required. Link the suspend block into + the list of suspended tasks on this semaphore. */ + CSC_Place_On_List((CS_NODE **) + &(semaphore -> sm_suspension_list), + &(suspend_ptr -> sm_suspend_link)); + } + else + { + + /* Get the priority of the current thread so the suspend block + can be placed in the appropriate place. */ + suspend_ptr -> sm_suspend_link.cs_priority = + TCC_Task_Priority(task); + + CSC_Priority_Place_On_List((CS_NODE **) + &(semaphore -> sm_suspension_list), + &(suspend_ptr -> sm_suspend_link)); + } + + /* Finally, suspend the calling task. Note that the suspension call + automatically clears the protection on the semaphore. */ + TCC_Suspend_Task((NU_TASK *) task, NU_SEMAPHORE_SUSPEND, + SMC_Cleanup, suspend_ptr, suspend); + + /* Pickup the return status. */ + status = suspend_ptr -> sm_return_status; + } + else + { + /* No suspension requested. Simply return an error status. */ + status = NU_UNAVAILABLE; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpSema(RT_PROF_OBTAIN_SEMAPHORE, semaphore,RT_PROF_FAIL); +#endif + } + } + + /* Release protection against access to the semaphore. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* SMC_Release_Semaphore */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function releases a previously obtained semaphore. If one */ +/* or more tasks are waiting, the first task is given the released */ +/* instance of the semaphore. Otherwise, the semaphore instance */ +/* counter is simply incremented. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* SMCE_Release_Semaphore Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove from suspend list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_System_Protect Protect semaphore */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* semaphore_ptr Semaphore control block ptr */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interfaces to */ +/* match those in prototype, */ +/* added register options, changed */ +/* protection logic to reduce */ +/* overhead, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS SMC_Release_Semaphore(NU_SEMAPHORE *semaphore_ptr) +{ + +R1 SM_SCB *semaphore; /* Semaphore control blk ptr */ +R2 SM_SUSPEND *suspend_ptr; /* Pointer to suspend block */ +STATUS preempt; /* Preemption flag */ +STATUS status; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input semaphore pointer into internal pointer. */ + semaphore = (SM_SCB *) semaphore_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_RELEASE_SEMAPHORE_ID, (UNSIGNED) semaphore, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Initialize the status as successful. */ + status = NU_SUCCESS; + + /* Protect against simultaneous access to the semaphore. */ + TCT_System_Protect(); + + /* Determine if another task is waiting on the semaphore. */ + if (semaphore -> sm_tasks_waiting) + { + + /* Yes, another task is waiting for an instance of the semaphore. */ + + /* Decrement the number of tasks waiting counter. */ + semaphore -> sm_tasks_waiting--; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpSema(RT_PROF_RELEASE_SEMAPHORE, semaphore,RT_PROF_OK); +#endif + + /* Remove the first suspended block from the list. */ + suspend_ptr = semaphore -> sm_suspension_list; + CSC_Remove_From_List((CS_NODE **) &(semaphore -> sm_suspension_list), + &(suspend_ptr -> sm_suspend_link)); + + /* Setup the appropriate return value. */ + suspend_ptr -> sm_return_status = NU_SUCCESS; + + /* Resume the suspended task. */ + preempt = + TCC_Resume_Task((NU_TASK *) suspend_ptr -> sm_suspended_task, + NU_SEMAPHORE_SUSPEND); + + /* Determine if a preempt condition is present. */ + if (preempt) + + /* Transfer control to the system if the resumed task function + detects a preemption condition. */ + TCT_Control_To_System(); + } + else + { + + /* Increment the semaphore instance counter. */ + semaphore -> sm_semaphore_count++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpSema(RT_PROF_RELEASE_SEMAPHORE, semaphore,RT_PROF_OK); +#endif + } + + /* Release protection against access to the semaphore. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* SMC_Cleanup */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for removing a suspension block */ +/* from a semaphore. It is not called unless a timeout or a task */ +/* terminate is in progress. Note that protection is already in */ +/* effect - the same protection at suspension time. This routine */ +/* must be called from Supervisor mode in Supervisor/User mode */ +/* switching kernels. */ +/* */ +/* CALLED BY */ +/* */ +/* TCC_Timeout Task timeout */ +/* TCC_Terminate Task terminate */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove suspend block from */ +/* the suspension list */ +/* */ +/* INPUTS */ +/* */ +/* information Pointer to suspend block */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +VOID SMC_Cleanup(VOID *information) +{ + +SM_SUSPEND *suspend_ptr; /* Suspension block pointer */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Use the information pointer as a suspend pointer. */ + suspend_ptr = (SM_SUSPEND *) information; + + /* By default, indicate that the service timed-out. It really does not + matter if this function is called from a terminate request since + the task does not resume. */ + suspend_ptr -> sm_return_status = NU_TIMEOUT; + + /* Decrement the number of tasks waiting counter. */ + (suspend_ptr -> sm_semaphore) -> sm_tasks_waiting--; + + /* Unlink the suspend block from the suspension list. */ + CSC_Remove_From_List((CS_NODE **) + &((suspend_ptr -> sm_semaphore) -> sm_suspension_list), + &(suspend_ptr -> sm_suspend_link)); + + /* Return to user mode */ + NU_USER_MODE(); +} + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/smce.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,377 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* smce.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* SM - Semaphore Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the error checking routines for the core */ +/* functions of the Semaphore component. This permits easy removal */ +/* of error checking logic when it is not needed. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* SMCE_Create_Semaphore Create a semaphore */ +/* SMCE_Delete_Semaphore Delete a semaphore */ +/* SMCE_Obtain_Semaphore Obtain an instance of a */ +/* semaphore */ +/* SMCE_Release_Semaphore Release an instance of a */ +/* semaphore */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* sm_extr.h Semaphore functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 05-15-1993 Corrected comment problem in */ +/* the header, making the new */ +/* version 1.0a */ +/* 05-15-1993 Verified version 1.0a */ +/* 03-01-1994 Split original error checking */ +/* file and changed function */ +/* interfaces, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "sm_extr.h" /* Semaphore functions */ + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* SMCE_Create_Semaphore */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the create semaphore function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* SMC_Create_Semaphore Actual semaphore create func.*/ +/* */ +/* INPUTS */ +/* */ +/* semaphore_ptr Semaphore control block ptr */ +/* name Semaphore name */ +/* initial_count Initial semaphore instance */ +/* count */ +/* suspend_type Suspension type */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_SEMAPHORE Semaphore control block ptr */ +/* is NULL */ +/* NU_INVALID_SUSPEND Semaphore suspension is */ +/* invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS SMCE_Create_Semaphore(NU_SEMAPHORE *semaphore_ptr, CHAR *name, + UNSIGNED initial_count, OPTION suspend_type) +{ + +SM_SCB *semaphore; /* Semaphore control blk ptr */ +STATUS status; /* Completion status */ + + + /* Move input semaphore pointer into internal pointer. */ + semaphore = (SM_SCB *) semaphore_ptr; + + /* Check for a NULL semaphore pointer or an already created semaphore. */ + if ((semaphore == NU_NULL) || (semaphore -> sm_id == SM_SEMAPHORE_ID)) + + /* Invalid semaphore control block pointer. */ + status = NU_INVALID_SEMAPHORE; + + else if ((suspend_type != NU_FIFO) && (suspend_type != NU_PRIORITY)) + + /* Invalid suspension type. */ + status = NU_INVALID_SUSPEND; + + else + + /* Call the actual service to create the semaphore. */ + status = SMC_Create_Semaphore(semaphore_ptr, name, initial_count, + suspend_type); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* SMCE_Delete_Semaphore */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the delete semaphore function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* SMC_Delete_Semaphore Actual delete semaphore func.*/ +/* */ +/* INPUTS */ +/* */ +/* semaphore_ptr Semaphore control block ptr */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_SEMAPHORE Invalid semaphore pointer */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS SMCE_Delete_Semaphore(NU_SEMAPHORE *semaphore_ptr) +{ + +SM_SCB *semaphore; /* Semaphore control blk ptr */ +STATUS status; /* Completion status */ + + + /* Move input semaphore pointer into internal pointer. */ + semaphore = (SM_SCB *) semaphore_ptr; + + /* Determine if the semaphore pointer is valid. */ + if ((semaphore) && (semaphore -> sm_id == SM_SEMAPHORE_ID)) + + /* Semaphore pointer is valid, call function to delete it. */ + status = SMC_Delete_Semaphore(semaphore_ptr); + + else + + /* Semaphore pointer is invalid, indicate in completion status. */ + status = NU_INVALID_SEMAPHORE; + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* SMCE_Obtain_Semaphore */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the obtain semaphore function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* SMC_Obtain_Semaphore Actual function to obtain an */ +/* instance of the semaphore */ +/* TCCE_Suspend_Error Check for illegal suspend */ +/* */ +/* INPUTS */ +/* */ +/* semaphore_ptr Semaphore control block ptr */ +/* suspend Suspension option if full */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_SEMAPHORE Invalid semaphore pointer */ +/* NU_INVALID_SUSPEND Suspension from non-task */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS SMCE_Obtain_Semaphore(NU_SEMAPHORE *semaphore_ptr, UNSIGNED suspend) +{ + +SM_SCB *semaphore; /* Semaphore control blk ptr */ +STATUS status; /* Completion status */ + + + /* Move input semaphore pointer into internal pointer. */ + semaphore = (SM_SCB *) semaphore_ptr; + + /* Determine if semaphore pointer is invalid. */ + if (semaphore == NU_NULL) + + /* Semaphore pointer is invalid, indicate in completion status. */ + status = NU_INVALID_SEMAPHORE; + + else if (semaphore -> sm_id != SM_SEMAPHORE_ID) + + /* Semaphore pointer is invalid, indicate in completion status. */ + status = NU_INVALID_SEMAPHORE; + + else if ((suspend) && (TCCE_Suspend_Error())) + + /* Suspension from an non-task thread. */ + status = NU_INVALID_SUSPEND; + + else + { + + /* Parameters are valid, call actual function. */ + status = SMC_Obtain_Semaphore(semaphore_ptr, suspend); + } + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* SMCE_Release_Semaphore */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the release semaphore function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* SMC_Release_Semaphore Actual release semaphore fct.*/ +/* */ +/* INPUTS */ +/* */ +/* semaphore_ptr Semaphore control block ptr */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_SEMAPHORE Invalid semaphore pointer */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS SMCE_Release_Semaphore(NU_SEMAPHORE *semaphore_ptr) +{ + +SM_SCB *semaphore; /* Semaphore control blk ptr */ +STATUS status; /* Completion status */ + + + /* Move input semaphore pointer into internal pointer. */ + semaphore = (SM_SCB *) semaphore_ptr; + + /* Determine if semaphore pointer is invalid. */ + if (semaphore == NU_NULL) + + /* Semaphore pointer is invalid, indicate in completion status. */ + status = NU_INVALID_SEMAPHORE; + + else if (semaphore -> sm_id != SM_SEMAPHORE_ID) + + /* Semaphore pointer is invalid, indicate in completion status. */ + status = NU_INVALID_SEMAPHORE; + + else + { + + /* Parameters are valid, call actual function. */ + status = SMC_Release_Semaphore(semaphore_ptr); + } + + /* Return the completion status. */ + return(status); +} + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/smd.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,86 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* smd.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* SM - Semaphore Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains global data structures for use within the */ +/* semaphore management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* SMD_Created_Semaphores_List Pointer to the linked-list */ +/* of created semaphores */ +/* SMD_Total_Semaphores Total number of created */ +/* semaphores */ +/* SMD_List_Protect Semaphore list protection */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* sm_defs.h Semaphore Management constant*/ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified copyright, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + +#include "sm_defs.h" /* Semaphore constants */ + + +/* SMD_Created_Semaphores_List is the head pointer of the linked list of + created semaphores. If the list is NU_NULL, there are no semaphores + created. */ + +CS_NODE *SMD_Created_Semaphores_List; + + +/* SMD_Total_Semaphores contains the number of currently created + semaphores. */ + +UNSIGNED SMD_Total_Semaphores; + + +/* SMD_List_Protect is a list protection structure used to block any other + thread from access to the created semaphore list. */ + +TC_PROTECT SMD_List_Protect; + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/smf.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,373 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* smf.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* SM - Semaphore Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains routines to obtain facts about the Semaphore */ +/* Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* SMF_Established_Semaphores Number of created semaphores */ +/* SMF_Semaphore_Pointers Build semaphore pointer list */ +/* SMF_Semaphore_Information Retrieve semaphore info */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* sm_extr.h Semaphore functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Initial version of semaphore */ +/* fact service file, version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 11-18-1996 Protected Informational service */ +/* from NULL Control Block pointers */ +/* creating 1.2a. (SPR220) */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "sm_extr.h" /* Semaphore functions */ +#include "hi_extr.h" /* History functions */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *SMD_Created_Semaphores_List; +extern UNSIGNED SMD_Total_Semaphores; +extern TC_PROTECT SMD_List_Protect; + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* SMF_Established_Semaphores */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the current number of established */ +/* semaphores. Semaphores previously deleted are no longer */ +/* considered established. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* SMD_Total_Semaphores Number of established */ +/* semaphores */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED SMF_Established_Semaphores(VOID) +{ + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Return the number of established semaphores. */ + return(SMD_Total_Semaphores); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* SMF_Semaphore_Pointers */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function builds a list of semaphore pointers, starting at */ +/* the specified location. The number of semaphore pointers */ +/* placed in the list is equivalent to the total number of */ +/* semaphores or the maximum number of pointers specified in the */ +/* call. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect created list */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* pointer_list Pointer to the list area */ +/* maximum_pointers Maximum number of pointers */ +/* */ +/* OUTPUTS */ +/* */ +/* pointers Number of semaphores placed */ +/* in the list */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected pointer retrieval */ +/* loop, resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED SMF_Semaphore_Pointers(NU_SEMAPHORE **pointer_list, + UNSIGNED maximum_pointers) +{ +CS_NODE *node_ptr; /* Pointer to each SMB */ +UNSIGNED pointers; /* Number of pointers in list*/ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Initialize the number of pointers returned. */ + pointers = 0; + + /* Protect against access to the list of created semaphores. */ + TCT_Protect(&SMD_List_Protect); + + /* Loop until all semaphore pointers are in the list or until the maximum + list size is reached. */ + node_ptr = SMD_Created_Semaphores_List; + while ((node_ptr) && (pointers < maximum_pointers)) + { + + /* Place the node into the destination list. */ + *pointer_list++ = (NU_SEMAPHORE *) node_ptr; + + /* Increment the pointers variable. */ + pointers++; + + /* Position the node pointer to the next node. */ + node_ptr = node_ptr -> cs_next; + + /* Determine if the pointer is at the head of the list. */ + if (node_ptr == SMD_Created_Semaphores_List) + + /* The list search is complete. */ + node_ptr = NU_NULL; + } + + /* Release protection against access to the list of created semaphores. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the number of pointers in the list. */ + return(pointers); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* SMF_Semaphore_Information */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns information about the specified semaphore. */ +/* However, if the supplied semaphore pointer is invalid, the */ +/* function simply returns an error status. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_System_Protect Protect semaphore */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* semaphore_ptr Pointer to the semaphore */ +/* name Destination for the name */ +/* current_count Destination for semaphore */ +/* instance count */ +/* suspend_type Destination for the type of */ +/* suspension */ +/* tasks_waiting Destination for the tasks */ +/* waiting count */ +/* first_task Destination for the pointer */ +/* to the first task waiting */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If a valid semaphore pointer */ +/* is supplied */ +/* NU_INVALID_SEMAPHORE If semaphore pointer invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 11-18-1996 Corrected SPR220. */ +/* */ +/*************************************************************************/ +STATUS SMF_Semaphore_Information(NU_SEMAPHORE *semaphore_ptr, CHAR *name, + UNSIGNED *current_count, OPTION *suspend_type, + UNSIGNED *tasks_waiting, NU_TASK **first_task) +{ + +SM_SCB *semaphore; /* Semaphore control blk ptr */ +INT i; /* Working integer variable */ +STATUS completion; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input semaphore pointer into internal pointer. */ + semaphore = (SM_SCB *) semaphore_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Determine if this semaphore id is valid. */ + if ((semaphore != NU_NULL) && (semaphore -> sm_id == SM_SEMAPHORE_ID)) + { + + /* Setup protection of the semaphore. */ + TCT_System_Protect(); + + /* The semaphore pointer is valid. Reflect this in the completion + status and fill in the actual information. */ + completion = NU_SUCCESS; + + /* Copy the semaphore's name. */ + for (i = 0; i < NU_MAX_NAME; i++) + *name++ = semaphore -> sm_name[i]; + + /* Determine the suspension type. */ + if (semaphore -> sm_fifo_suspend) + *suspend_type = NU_FIFO; + else + *suspend_type = NU_PRIORITY; + + /* Return the current semaphore available instance count. */ + *current_count = semaphore -> sm_semaphore_count; + + /* Retrieve the number of tasks waiting and the pointer to the + first task waiting. */ + *tasks_waiting = semaphore -> sm_tasks_waiting; + if (semaphore -> sm_suspension_list) + + /* There is a task waiting. */ + *first_task = (NU_TASK *) + (semaphore -> sm_suspension_list) -> sm_suspended_task; + else + + /* There are no tasks waiting. */ + *first_task = NU_NULL; + + /* Release protection of the semaphore. */ + TCT_Unprotect(); + } + else + + /* Indicate that the semaphore pointer is invalid. */ + completion = NU_INVALID_SEMAPHORE; + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the appropriate completion status. */ + return(completion); +} + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/smi.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,125 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* smi.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* SM - Semaphore Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the initialization routine for the semaphore */ +/* management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* SMI_Initialize Semaphore Management Init. */ +/* */ +/* DEPENDENCIES */ +/* */ +/* sm_defs.h Semaphore component constants*/ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified copyright, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "sm_defs.h" /* Semaphore constants */ +#include "sm_extr.h" /* Semaphore interfaces */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *SMD_Created_Semaphores_List; +extern UNSIGNED SMD_Total_Semaphores; +extern TC_PROTECT SMD_List_Protect; + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* SMI_Initialize */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function initializes the data structures that control the */ +/* operation of the Semaphore component (SM). There are no */ +/* semaphores initially. This routine must be called from */ +/* Supervisor mode in Supervisor/User mode switching kernels. */ +/* */ +/* CALLED BY */ +/* */ +/* INC_Initialize System initialization */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* SMD_Created_Semaphores_List List of created semaphores */ +/* SMD_Total_Semaphores Number of created semaphores */ +/* SMD_List_Protect Protection for semaphore list*/ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +VOID SMI_Initialize(VOID) +{ + + /* Initialize the created semaphore list to NU_NULL. */ + SMD_Created_Semaphores_List = NU_NULL; + + /* Initialize the total number of created semaphores to 0. */ + SMD_Total_Semaphores = 0; + + /* Initialize the list protection structure. */ + SMD_List_Protect.tc_tcb_pointer = NU_NULL; +} + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/sms.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,214 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* sms.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* SM - Semaphore Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the supplemental routines for the Semaphore */ +/* Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* SMS_Reset_Semaphore Reset semaphore */ +/* terminate condition */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* sm_extr.h Semaphore functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Created initial version 1.1 from */ +/* routines originally in core */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "sm_extr.h" /* Semaphore functions */ +#include "hi_extr.h" /* History functions */ +#include "profiler.h" /* ProView interface */ + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* SMS_Reset_Semaphore */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function resets a semaphore back to the initial state. All */ +/* tasks suspended on the semaphore are resumed with the reset */ +/* completion status. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* SMSE_Reset_Semaphore Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a suspended task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_System_Protect Protect semaphore */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* semaphore_ptr Semaphore control block ptr */ +/* initial_count Initial count to reset the */ +/* semaphore to */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interface to */ +/* match the prototype, added */ +/* register variable logic, */ +/* optimized protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS SMS_Reset_Semaphore(NU_SEMAPHORE *semaphore_ptr, + UNSIGNED initial_count) +{ + +R1 SM_SCB *semaphore; /* Semaphore control blk ptr */ +R2 SM_SUSPEND *suspend_ptr; /* Suspend block pointer */ +R3 SM_SUSPEND *next_ptr; /* Next suspend block pointer*/ +STATUS preempt; /* Status for resume call */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input semaphore pointer into internal pointer. */ + semaphore = (SM_SCB *) semaphore_ptr; + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_RESET_SEMAPHORE_ID, (UNSIGNED) semaphore, + (UNSIGNED) initial_count, (UNSIGNED) 0); + +#endif + + /* Protect against access to the semaphore. */ + TCT_System_Protect(); + + /* Pickup the suspended task pointer list. */ + suspend_ptr = semaphore -> sm_suspension_list; + + /* Walk the chain task(s) currently suspended on the semaphore. */ + preempt = 0; + while (suspend_ptr) + { + + /* Resume the suspended task. Insure that the status returned is + NU_SEMAPHORE_RESET. */ + suspend_ptr -> sm_return_status = NU_SEMAPHORE_RESET; + + /* Point to the next suspend structure in the link. */ + next_ptr = (SM_SUSPEND *) (suspend_ptr -> sm_suspend_link.cs_next); + + /* Resume the specified task. */ + preempt = preempt | + TCC_Resume_Task((NU_TASK *) suspend_ptr -> sm_suspended_task, + NU_SEMAPHORE_SUSPEND); + + /* Determine if the next is the same as the current pointer. */ + if (next_ptr == semaphore -> sm_suspension_list) + + /* Clear the suspension pointer to signal the end of the list + traversal. */ + suspend_ptr = NU_NULL; + else + + /* Move the next pointer into the suspend block pointer. */ + suspend_ptr = next_ptr; + } + + /* Initialize the semaphore. */ + semaphore -> sm_semaphore_count = initial_count; + semaphore -> sm_tasks_waiting = 0; + semaphore -> sm_suspension_list = NU_NULL; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpSema(RT_PROF_RESET_SEMAPHORE,(SM_SCB *) semaphore, RT_PROF_OK); +#endif + + /* Determine if preemption needs to occur. */ + if (preempt) + + /* Transfer control to system to facilitate preemption. */ + TCT_Control_To_System(); + + /* Release protection against access to the semaphore. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return a successful completion. */ + return(NU_SUCCESS); +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/smse.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,134 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* smse.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* SM - Semaphore Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the error checking routines for the */ +/* supplemental functions of the Semaphore component. This permits */ +/* easy removal of error checking logic when it is not needed. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* SMSE_Reset_Semaphore Reset a semaphore */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* sm_extr.h Semaphore functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Created initial version 1.1 from */ +/* routines originally in core */ +/* error checking file */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "sm_extr.h" /* Semaphore functions */ + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* SMSE_Reset_Semaphore */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the reset semaphore function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* SMS_Reset_Semaphore Actual reset semaphore func. */ +/* */ +/* INPUTS */ +/* */ +/* semaphore_ptr Semaphore control block ptr */ +/* initial_count Initial count to reset the */ +/* semaphore to */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_SEMAPHORE Invalid semaphore pointer */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS SMSE_Reset_Semaphore(NU_SEMAPHORE *semaphore_ptr, + UNSIGNED initial_count) +{ + +SM_SCB *semaphore; /* Semaphore control blk ptr */ +STATUS status; /* Completion status */ + + + /* Move input semaphore pointer into internal pointer. */ + semaphore = (SM_SCB *) semaphore_ptr; + + /* Determine if the semaphore pointer is valid. */ + if ((semaphore) && (semaphore -> sm_id == SM_SEMAPHORE_ID)) + + /* Semaphore pointer is valid, call function to reset it. */ + status = SMS_Reset_Semaphore(semaphore_ptr, initial_count); + + else + + /* Semaphore pointer is invalid, indicate in completion status. */ + status = NU_INVALID_SEMAPHORE; + + /* Return completion status. */ + return(status); +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/tc_defs.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,245 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* tc_defs.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* TC - Thread Control */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains data structure definitions and constants for */ +/* the component that controls the various threads of execution in */ +/* system. Threads include tasks, HISRs, signal handlers, etc. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* TC_TCB Task Control Block */ +/* TC_HCB HISR Control Block */ +/* TC_PROTECT Task/HISR protection struct */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_defs.h Common service definitions */ +/* tm_defs.h Timer control definitions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 06-01-1993 Added padding conditional into */ +/* TC_TCB structure, making */ +/* version 1.0a */ +/* 06-01-1993 Verified version 1.0a */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* added four reserved words in */ +/* both the task and HISR blocks, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-07-1999 Release 1.11mA */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "cs_defs.h" /* Common service constants */ +#include "tm_defs.h" /* Timer control structures */ + + +/* Check to see if the file has been included already. */ + +#ifndef TC_DEFS +#define TC_DEFS + + +/* Define constants local to this component. */ + +#define TC_TASK_ID 0x5441534bUL +#define TC_HISR_ID 0x48495352UL +#define TC_PRIORITIES 256 +#define TC_HISR_PRIORITIES 3 +#define TC_MAX_GROUPS (TC_PRIORITIES/8) +#define TC_HIGHEST_MASK 0x000000FFUL +#define TC_NEXT_HIGHEST_MASK 0x0000FF00UL +#define TC_NEXT_LOWEST_MASK 0x00FF0000UL +#define TC_LOWEST_MASK 0xFF000000UL + +/* Define the Task Control Block data type. */ + +typedef struct TC_TCB_STRUCT +{ + /* Standard thread information first. This information is used by + the target dependent portion of this component. Changes made + to this area of the structure can have undesirable side effects. */ + + CS_NODE tc_created; /* Node for linking to */ + /* created task list */ + UNSIGNED tc_id; /* Internal TCB ID */ + CHAR tc_name[NU_MAX_NAME]; /* Task name */ + DATA_ELEMENT tc_status; /* Task status */ + BOOLEAN tc_delayed_suspend; /* Delayed task suspension*/ + DATA_ELEMENT tc_priority; /* Task priority */ + BOOLEAN tc_preemption; /* Task preemption enable */ + UNSIGNED tc_scheduled; /* Task scheduled count */ + UNSIGNED tc_cur_time_slice; /* Current time slice */ + VOID *tc_stack_start; /* Stack starting address */ + VOID *tc_stack_end; /* Stack ending address */ + VOID *tc_stack_pointer; /* Task stack pointer */ + UNSIGNED tc_stack_size; /* Task stack's size */ + UNSIGNED tc_stack_minimum; /* Minimum stack size */ + struct TC_PROTECT_STRUCT + *tc_current_protect; /* Current protection */ + VOID *tc_saved_stack_ptr; /* Previous stack pointer */ + UNSIGNED tc_time_slice; /* Task time slice value */ + + /* Information after this point is not used in the target dependent + portion of this component. Hence, changes in the following section + should not impact assembly language routines. */ + struct TC_TCB_STRUCT + *tc_ready_previous, /* Previously ready TCB */ + *tc_ready_next; /* next and previous ptrs */ + + /* Task control information follows. */ + + UNSIGNED tc_priority_group; /* Priority group mask bit*/ + struct TC_TCB_STRUCT + **tc_priority_head; /* Pointer to list head */ + DATA_ELEMENT *tc_sub_priority_ptr; /* Pointer to sub-group */ + DATA_ELEMENT tc_sub_priority; /* Mask of sub-group bit */ + DATA_ELEMENT tc_saved_status; /* Previous task status */ + BOOLEAN tc_signal_active; /* Signal active flag */ + +#if PAD_3 + DATA_ELEMENT tc_padding[PAD_3]; +#endif + + /* Task entry function */ + VOID (*tc_entry)(UNSIGNED, VOID *); + UNSIGNED tc_argc; /* Optional task argument */ + VOID *tc_argv; /* Optional task argument */ + VOID (*tc_cleanup) (VOID *);/* Clean-up routine */ + VOID *tc_cleanup_info; /* Clean-up information */ + struct TC_PROTECT_STRUCT + *tc_suspend_protect; /* Protection at time of */ + /* task suspension */ + + /* Task timer information. */ + INT tc_timer_active; /* Active timer flag */ + TM_TCB tc_timer_control; /* Timer control block */ + + /* Task signal control information. */ + + UNSIGNED tc_signals; /* Current signals */ + UNSIGNED tc_enabled_signals; /* Enabled signals */ + + /* tc_saved_status and tc_signal_active are now defined above in an + attempt to keep DATA_ELEMENT types together. */ + + /* Signal handling routine. */ + VOID (*tc_signal_handler) (UNSIGNED); + + /* Reserved words for the system and a single reserved word for the + application. */ + UNSIGNED tc_system_reserved_1; /* System reserved word */ + UNSIGNED tc_system_reserved_2; /* System reserved word */ + UNSIGNED tc_system_reserved_3; /* System reserved word */ + UNSIGNED tc_app_reserved_1; /* Application reserved */ + + /* This information is accessed in assembly */ +#if ((NU_SUPERV_USER_MODE == 1)||(NU_MODULE_SUPPORT == 1)) + UNSIGNED tc_su_mode; /* Supervisor/User mode indicator */ + UNSIGNED tc_module; /* Module identifier */ +#endif + +} TC_TCB; + + +/* Define the High-Level Interrupt Service Routine Control Block data type. */ + +typedef struct TC_HCB_STRUCT +{ + /* Standard thread information first. This information is used by + the target dependent portion of this component. Changes made + to this area of the structure can have undesirable side effects. */ + + CS_NODE tc_created; /* Node for linking to */ + /* created task list */ + UNSIGNED tc_id; /* Internal TCB ID */ + CHAR tc_name[NU_MAX_NAME]; /* HISR name */ + DATA_ELEMENT tc_not_used_1; /* Not used field */ + DATA_ELEMENT tc_not_used_2; /* Not used field */ + DATA_ELEMENT tc_priority; /* HISR priority */ + DATA_ELEMENT tc_not_used_3; /* Not used field */ + UNSIGNED tc_scheduled; /* HISR scheduled count */ + UNSIGNED tc_cur_time_slice; /* Not used in HISR */ + VOID *tc_stack_start; /* Stack starting address */ + VOID *tc_stack_end; /* Stack ending address */ + VOID *tc_stack_pointer; /* HISR stack pointer */ + UNSIGNED tc_stack_size; /* HISR stack's size */ + UNSIGNED tc_stack_minimum; /* Minimum stack size */ + struct TC_PROTECT_STRUCT + *tc_current_protect; /* Current protection */ + struct TC_HCB_STRUCT + *tc_active_next; /* Next activated HISR */ + UNSIGNED tc_activation_count; /* Activation counter */ + VOID (*tc_entry)(VOID); /* HISR entry function */ + + /* Information after this point is not used in the target dependent + portion of this component. Hence, changes in the following section + should not impact assembly language routines. */ + + + /* Reserved words for the system and a single reserved word for the + application. */ + UNSIGNED tc_system_reserved_1; /* System reserved word */ + UNSIGNED tc_system_reserved_2; /* System reserved word */ + UNSIGNED tc_system_reserved_3; /* System reserved word */ + UNSIGNED tc_app_reserved_1; /* Application reserved */ + + /* This information is accessed in assembly */ +#if ((NU_SUPERV_USER_MODE == 1)||(NU_MODULE_SUPPORT == 1)) + UNSIGNED tc_su_mode; /* Supervisor/User mode indicator */ + UNSIGNED tc_module; /* Module identifier */ +#endif + +} TC_HCB; + + +/* Define the Task/HISR protection structure type. */ + +typedef struct TC_PROTECT_STRUCT +{ + TC_TCB *tc_tcb_pointer; /* Owner of the protection */ + UNSIGNED tc_thread_waiting; /* Waiting thread flag */ +} TC_PROTECT; + +#endif + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/tc_extr.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,250 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* tc_extr.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* TC - Thread Control */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains function prototypes of all functions */ +/* accessible to other components. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* tc_defs.h Thread Control constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Added validation utility for */ +/* error checking functions for */ +/* resume service and resume */ +/* driver, resulting in */ +/* version 1.0a */ +/* 03-01-1994 Verified version 1.0a */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* added system protect pseudo */ +/* function, added set suspend */ +/* protect pseudo function, */ +/* added optimization for targets */ +/* able to access pointers in a */ +/* single instruction, changed */ +/* function names due to changes */ +/* in file structure, resulting */ +/* in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/* 01-24-1996 Corrected a type on line 200: */ +/* TCT_Control_Interrupts, */ +/* resulting in version 1.1+ */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "tc_defs.h" /* Include TC constants */ + + +/* Check to see if the file has been included already. */ + +#ifndef TC_EXTR +#define TC_EXTR + + +/* Define external reference for the system protection. */ + +extern TC_PROTECT TCD_System_Protect; +extern VOID *TCD_Current_Thread; + + +/* Initialization functions. */ + +VOID TCI_Initialize(VOID); + + +/* Core error checking functions. */ + +#ifndef NU_NO_ERROR_CHECKING +BOOLEAN TCC_Validate_Resume(OPTION resume_type, NU_TASK *task_ptr); +#endif + +STATUS TCCE_Activate_HISR(NU_HISR *hisr_ptr); +STATUS TCCE_Create_Task(NU_TASK *task_ptr, CHAR *name, + VOID (*task_entry)(UNSIGNED, VOID *), UNSIGNED argc, + VOID *argv, VOID *stack_address, UNSIGNED stack_size, + OPTION priority, UNSIGNED time_slice, + OPTION preempt, OPTION auto_start); +STATUS TCCE_Reset_Task(NU_TASK *task_ptr, UNSIGNED argc, VOID *argv); +STATUS TCCE_Create_HISR(NU_HISR *hisr_ptr, CHAR *name, + VOID (*hisr_entry)(VOID), OPTION priority, + VOID *stack_address, UNSIGNED stack_size); +STATUS TCCE_Terminate_Task(NU_TASK *task_ptr); +STATUS TCCE_Delete_Task(NU_TASK *task_ptr); +STATUS TCCE_Delete_HISR(NU_HISR *hisr_ptr); +STATUS TCCE_Resume_Service(NU_TASK *task_ptr); +STATUS TCCE_Suspend_Service(NU_TASK *task_ptr); +VOID TCCE_Relinquish(VOID); +VOID TCCE_Task_Sleep(UNSIGNED ticks); +STATUS TCCE_Validate_Resume(OPTION resume_type, NU_TASK *task_ptr); +INT TCCE_Suspend_Error(VOID); +STATUS TCFE_Task_Information(NU_TASK *task_ptr, CHAR *name, + DATA_ELEMENT *status, UNSIGNED *scheduled_count, + DATA_ELEMENT *priority, OPTION *preempt, UNSIGNED *time_slice, + VOID **stack_base, UNSIGNED *stack_size, + UNSIGNED *minimum_stack); + + +/* Supplemental error checking functions. */ + +OPTION TCSE_Change_Priority(NU_TASK *task_ptr, OPTION new_priority); +OPTION TCSE_Change_Preemption(OPTION preempt); +UNSIGNED TCSE_Change_Time_Slice(NU_TASK *task_ptr, UNSIGNED time_slice); +UNSIGNED TCSE_Control_Signals(UNSIGNED signal_enable_mask); +UNSIGNED TCSE_Receive_Signals(VOID); +STATUS TCSE_Register_Signal_Handler(VOID (*signal_handler)(UNSIGNED)); +STATUS TCSE_Send_Signals(NU_TASK *task_ptr, UNSIGNED signals); + + +/* Core processing functions. */ + +STATUS TCT_Activate_HISR(NU_HISR *hisr_ptr); +STATUS TCC_Create_Task(NU_TASK *task_ptr, CHAR *name, + VOID (*task_entry)(UNSIGNED, VOID *), UNSIGNED argc, + VOID *argv, VOID *stack_address, UNSIGNED stack_size, + OPTION priority, UNSIGNED time_slice, + OPTION preempt, OPTION auto_start); +STATUS TCC_Reset_Task(NU_TASK *task_ptr, UNSIGNED argc, VOID *argv); +STATUS TCC_Create_HISR(NU_HISR *hisr_ptr, CHAR *name, + VOID (*hisr_entry)(VOID), OPTION priority, + VOID *stack_address, UNSIGNED stack_size); +STATUS TCC_Terminate_Task(NU_TASK *task_ptr); +STATUS TCC_Delete_Task(NU_TASK *task_ptr); +STATUS TCC_Delete_HISR(NU_HISR *hisr_ptr); +STATUS TCC_Resume_Task(NU_TASK *task_ptr, OPTION suspend_type); +STATUS TCC_Resume_Service(NU_TASK *task_ptr); +VOID TCC_Suspend_Task(NU_TASK *task_ptr, OPTION suspend_type, + VOID (*cleanup)(VOID *), + VOID *information, UNSIGNED timeout); +STATUS TCC_Suspend_Service(NU_TASK *task_ptr); +VOID TCC_Task_Timeout(NU_TASK *task_ptr); +VOID TCC_Task_Sleep(UNSIGNED ticks); +VOID TCC_Relinquish(VOID); +VOID TCC_Time_Slice(NU_TASK *task_ptr); +NU_TASK *TCC_Current_Task_Pointer(VOID); +NU_HISR *TCC_Current_HISR_Pointer(VOID); +VOID TCC_Dispatch_LISR(INT vector); +STATUS TCC_Register_LISR(INT vector, VOID (*new_lisr)(INT), + VOID (**old_lisr)(INT)); + + +/* Supplemental functions. */ + +OPTION TCS_Change_Priority(NU_TASK *task_ptr, OPTION new_priority); +OPTION TCS_Change_Preemption(OPTION preempt); +UNSIGNED TCS_Change_Time_Slice(NU_TASK *task_ptr, UNSIGNED time_slice); +UNSIGNED TCS_Control_Signals(UNSIGNED signal_enable_mask); +UNSIGNED TCS_Receive_Signals(VOID); +STATUS TCS_Register_Signal_Handler(VOID (*signal_handler)(UNSIGNED)); +STATUS TCS_Send_Signals(NU_TASK *task, UNSIGNED signals); + + +/* Information retrieval functions. */ + +UNSIGNED TCF_Established_Tasks(VOID); +UNSIGNED TCF_Established_HISRs(VOID); +STATUS TCF_Task_Information(NU_TASK *task, CHAR *name, + DATA_ELEMENT *status, UNSIGNED *scheduled_count, + OPTION *priority, OPTION *preempt, + UNSIGNED *time_slice, VOID **stack_base, + UNSIGNED *stack_size, UNSIGNED *minimum_stack); +STATUS TCF_HISR_Information(NU_HISR *hisr, CHAR *name, + UNSIGNED *scheduled_count, DATA_ELEMENT *priority, + VOID **stack_base, UNSIGNED *stack_size, + UNSIGNED *minimum_stack); +UNSIGNED TCF_Task_Pointers(NU_TASK **pointer_list, + UNSIGNED maximum_pointers); +UNSIGNED TCF_HISR_Pointers(NU_HISR **pointer_list, + UNSIGNED maximum_pointers); + +/* Target dependent functions. */ + +UNSIGNED TCT_Check_Stack(VOID); +VOID TCT_Schedule(VOID); +VOID TCT_Restore_Interrupts(VOID); +VOID TCT_Protect(TC_PROTECT *protect); +VOID TCT_Unprotect(VOID); +VOID TCT_Unprotect_Specific(TC_PROTECT *protect); +VOID TCT_Set_Current_Protect(TC_PROTECT *protect); +VOID TCT_Control_To_System(VOID); +INT TCT_Control_Interrupts(INT new_level); +INT TCT_Local_Control_Interrupts(INT new_level); + +#ifdef NU_ENABLE_STACK_CHECK +#define NU_CHECK_STACK() TCT_Check_Stack() +#else /* no stack checking */ +#define NU_CHECK_STACK() ((void)0) +#endif /* NU_ENABLE_STACK_CHECK */ + + +/* Determine if pointers are accessible with a single instruction. If so, + just reference the pointer directly. Otherwise, call the assembly + service. */ + +#if NU_POINTER_ACCESS == 1 +extern TC_TCB *TCD_Execute_Task; +#define TCT_Current_Thread() TCD_Current_Thread +#define TCT_Set_Execute_Task(task) TCD_Execute_Task = task +#else +VOID *TCT_Current_Thread(VOID); +VOID TCT_Set_Execute_Task(TC_TCB *task); +#endif + +/* Define pseudo function used by internal components of the system. */ + +#define TCT_System_Protect() TCT_Protect(&TCD_System_Protect) +#define TCT_System_Unprotect() \ + TCT_Unprotect_Specific(&TCD_System_Protect) +#define TCT_Set_Suspend_Protect(protect) \ + ((TC_TCB *) TCD_Current_Thread) -> tc_suspend_protect = \ + (TC_PROTECT *) protect +#define TCT_Get_Current_Protect() \ + ((TC_TCB *) TCD_Current_Thread) -> tc_current_protect +#define TCC_Task_Priority(task) ((TC_TCB *) (task)) -> tc_priority +#endif + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/tcc.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,3060 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* tcc.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* TC - Thread Control */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the core routines for the Thread Control */ +/* component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* TCC_Create_Task Create a task */ +/* TCC_Delete_Task Delete a task */ +/* TCC_Create_HISR Create HISR */ +/* TCC_Delete_HISR Delete HISR */ +/* TCC_Reset_Task Reset the specified task */ +/* TCC_Terminate_Task Terminate the specified task */ +/* TCC_Resume_Task Resume a task */ +/* TCC_Resume_Service Resume a task service call */ +/* TCC_Suspend_Task Suspend a task */ +/* TCC_Suspend_Service Suspend a task service call */ +/* TCC_Task_Timeout Task timeout function */ +/* TCC_Task_Sleep Task sleep request */ +/* TCC_Relinquish Relinquish task execution */ +/* TCC_Time_Slice Process task time-slice */ +/* TCC_Current_Task_Pointer Retrieve current task pointer*/ +/* TCC_Current_HISR_Pointer Retrieve current HISR pointer*/ +/* TCC_Task_Shell Task execution shell */ +/* TCC_Signal_Shell Signal execution shell */ +/* TCC_Dispatch_LISR Dispatch LISR routine */ +/* TCC_Register_LISR Register an LISR */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* in_extr.h Initialization/Interrupt */ +/* functions */ +/* tm_extr.h Timer Control function */ +/* er_extr.h Error handling function */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 05-15-1993 Corrected comment problems in */ +/* TCC_Control_Signals and */ +/* TCC_Register_Signal_Handler, */ +/* making version 1.0a */ +/* 05-15-1993 Verified version 1.0a */ +/* 06-01-1993 Modified a multi-line comment */ +/* after a #include directive */ +/* that gave some compilers a */ +/* problem, making version 1.0b */ +/* 06-01-1993 Verified version 1.0b */ +/* 08-09-1993 Corrected pointer retrieval */ +/* loop, resulting in version 1.0c */ +/* 08-09-1993 Verified version 1.0c */ +/* 09-19-1993 Corrected an initialization */ +/* problem of de-referencing a */ +/* NULL pointer, resulting in */ +/* version 1.0d */ +/* 09-19-1993 Verified version 1.0d */ +/* 11-01-1993 Added logic to save unhandled */ +/* interrupt vector number in */ +/* a global variable, resulting */ +/* in version 1.0e */ +/* 11-01-1993 Verified version 1.0e */ +/* 02-01-1994 Corrected a suspension with */ +/* timeout problem that caused */ +/* unconditional task suspension */ +/* for timeouts and sleeps for 1 */ +/* tick, resulting in version 1.0f */ +/* 02-01-1994 Verified version 1.0f */ +/* 03-01-1994 Added another routine that */ +/* validates resume calls with */ +/* the appropriate protection and */ +/* added code to clear cleanup */ +/* information at task create and */ +/* task resume time, resulting in */ +/* version 1.0g */ +/* 03-01-1994 Verified version 1.0g */ +/* 03-01-1994 Moved non-core functions into */ +/* supplemental files, changed */ +/* function interfaces to match */ +/* those in prototype, added */ +/* register options, fixed bug */ +/* in suspending current task from */ +/* a HISR, added a system protect */ +/* structure to reduce overhead */ +/* in protection, moved resume */ +/* validate to error checking */ +/* file, resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 12-18-1995 Modified TCC_Resume_Service, */ +/* resulting in version 1.1+ */ +/* (SPR 36, 64, 66, 77) */ +/* 04-17-1996 updated to version 1.2 */ +/* 06-01-1996 Modified TCC_Suspend_Task */ +/* (SPR152) creating version 1.2a */ +/* 10-29-1997 Modified TCC_Resume_Task */ +/* (SPR115) creating vresion 1.2b */ +/* 01-23-1998 Released version 1.2b */ +/* 03-20-1998 Corrected problem where tasks */ +/* created with NU_NO_PREEMPT in */ +/* Application_Initialize would */ +/* start in the order of creation */ +/* and not in priority order. */ +/* SPR455 creates version 1.2c */ +/* 03-24-1998 Released version 1.3. */ +/* 10-02-1998 Another protect problem (1.3a) */ +/* 10-02-1998 Corrected a problem where a */ +/* a timer expiration occurs */ +/* during signal handler execution */ +/* and causes the task to never */ +/* run again (SPR 923) creating */ +/* version 1.3b. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + +#include "in_defs.h" /* Initialization defines */ +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "in_extr.h" /* Initialization/Interrupt */ + /* functions */ +#include "tm_extr.h" /* Timer control functions */ +#include "er_extr.h" /* Error handling function */ +#include "hi_extr.h" /* History functions */ +#include "profiler.h" /* Nucleus Profiling header */ + +#if ((defined(NU_MODULE_SUPPORT)) && (NU_MODULE_SUPPORT > 0)) +#include "module/inc/ms_defs.h" /* MS_Module typedef */ +#endif + +/* Define external inner-component global data references. */ + +extern INT INC_Initialize_State; +extern CS_NODE *TCD_Created_Tasks_List; +extern UNSIGNED TCD_Total_Tasks; +extern TC_TCB *TCD_Priority_List[TC_PRIORITIES]; +extern UNSIGNED TCD_Priority_Groups; +extern DATA_ELEMENT TCD_Sub_Priority_Groups[TC_MAX_GROUPS]; +extern UNSIGNED_CHAR TCD_Lowest_Set_Bit[]; +extern INT TCD_Highest_Priority; +extern TC_TCB *TCD_Execute_Task; +extern VOID *TCD_Current_Thread; +extern UNSIGNED_CHAR TCD_Registered_LISRs[NU_MAX_VECTORS+1]; +extern VOID (*TCD_LISR_Pointers[NU_MAX_LISRS+1])(INT vector); +extern INT TCD_Interrupt_Count; +extern INT TCD_Stack_Switched; +extern TC_PROTECT TCD_List_Protect; +extern TC_PROTECT TCD_System_Protect; +extern TC_PROTECT TCD_LISR_Protect; +extern CS_NODE *TCD_Created_HISRs_List; +extern UNSIGNED TCD_Total_HISRs; +extern TC_PROTECT TCD_HISR_Protect; +extern INT TCD_Unhandled_Interrupt; + + +/* Define external inner-component function calls that are not available to + other components. */ + +VOID TCT_Build_Task_Stack(TC_TCB *task_ptr); +VOID TCT_Build_HISR_Stack(TC_HCB *hisr_ptr); +VOID TCT_Build_Signal_Frame(TC_TCB *task_ptr); +VOID TCT_Protect_Switch(TC_TCB *task); +VOID TCT_Signal_Exit(VOID); + + +/* Define internal function calls. */ + +VOID TCC_Signal_Shell(VOID); + + +#if defined(NU_MODULE_SUPPORT) && (NU_MODULE_SUPPORT > 0) + +/* Define service routines "privately" imported from other components */ +extern MS_MODULE* msd_current_module; + +STATUS MSC_Bind_Module_HISR(MS_MODULE* module, TC_HCB* hisr); +STATUS MSC_Bind_Module_Task(MS_MODULE* module, TC_TCB* task); + +#endif /* NU_MODULE_SUPPORT */ + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCC_Create_Task */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function creates a task and then places it on the list of */ +/* created tasks. All the resources necessary to create the task */ +/* are supplied to this routine. If specified, the newly created */ +/* task is started. Otherwise, it is left in a suspended state. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* TCCE_Create_Task Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Add TCB to linked-list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Start the created task */ +/* TCT_Build_Task_Stack Build an initial task stack */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Protect Protect created task list */ +/* TCT_Unprotect Release protection of list */ +/* TMC_Init_Task_Timer Initialize the task's timer */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Task control block pointer */ +/* name Task name */ +/* task_entry Entry function of the task */ +/* argc Optional task parameter */ +/* argv Optional task parameter */ +/* stack_address Pointer to start of stack */ +/* stack_size Size of task stack in bytes */ +/* priority Task priority */ +/* time_slice Task time slice */ +/* preempt Task preemptability flag */ +/* auto_start Automatic task start */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* added system protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TCC_Create_Task(NU_TASK *task_ptr, CHAR *name, + VOID (*task_entry)(UNSIGNED, VOID *), UNSIGNED argc, VOID *argv, + VOID *stack_address, UNSIGNED stack_size, + OPTION priority, UNSIGNED time_slice, + OPTION preempt, OPTION auto_start) +{ + +R1 TC_TCB *task; /* Task control block ptr */ +R2 INT i; /* Working index variable */ +STATUS status = NU_SUCCESS; + +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input task pointer into internal pointer. */ + task = (TC_TCB *) task_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_CREATE_TASK_ID, (UNSIGNED) task, + (UNSIGNED) name, (UNSIGNED) task_entry); + +#endif + + /* First, clear the task ID just in case it is an old Task + Control Block. */ + task -> tc_id = 0; + + /* Fill in the task name. */ + for (i = 0; i < NU_MAX_NAME; i++) + task -> tc_name[i] = name[i]; + + /* Fill in the basic task information. */ + task -> tc_entry = task_entry; + task -> tc_argc = argc; + task -> tc_argv = argv; + task -> tc_status = NU_PURE_SUSPEND; + task -> tc_delayed_suspend = NU_FALSE; + task -> tc_scheduled = 0; + task -> tc_time_slice = time_slice; + task -> tc_cur_time_slice = time_slice; + task -> tc_current_protect = NU_NULL; + task -> tc_suspend_protect = NU_NULL; + task -> tc_cleanup = NU_NULL; + task -> tc_cleanup_info = NU_NULL; + + /* Setup task's preemption posture. */ + if (preempt == NU_PREEMPT) + task -> tc_preemption = NU_TRUE; + else + task -> tc_preemption = NU_FALSE; + + /* Fill in information about the task's stack. */ + task -> tc_stack_start = stack_address; + task -> tc_stack_end = 0; + task -> tc_stack_size = stack_size; + task -> tc_stack_minimum = stack_size; + + /* Setup priority information for the task. There are two bit maps + associated with each task. The first bit map indicates which group + of 8-priorities it is. The second bit map indicates the actual + priority within the group. */ + task -> tc_priority = priority; + task -> tc_priority_head = &(TCD_Priority_List[priority]); + task -> tc_sub_priority = (DATA_ELEMENT) (1 << (priority & 7)); + priority = priority >> 3; + task -> tc_priority_group = ((UNSIGNED) 1) << priority; + task -> tc_sub_priority_ptr = &(TCD_Sub_Priority_Groups[priority]); + + /* Initialize link pointers. */ + task -> tc_created.cs_previous = NU_NULL; + task -> tc_created.cs_next = NU_NULL; + task -> tc_ready_previous = NU_NULL; + task -> tc_ready_next = NU_NULL; + + /* Build a stack frame for this task by calling TCT_Build_Task_Stack. */ + TCT_Build_Task_Stack(task); + + /* Initialize the signal information of the task. */ + task -> tc_signals = 0; + task -> tc_enabled_signals = 0; + task -> tc_signal_handler = 0; + task -> tc_signal_active = NU_FALSE; + /* Initialize additional kernel options data */ + +#if (NU_SUPERV_USER_MODE == 1) + task->tc_su_mode = 0; /* Initially in User mode */ + task->tc_module = 0; /* Not initially bound to a module */ +#endif + + /* Initialize the task timer. */ + task -> tc_timer_active = NU_FALSE; + TMC_Init_Task_Timer(&(task -> tc_timer_control), (VOID *) task); + + /* Protect the list of created tasks. */ + TCT_Protect(&TCD_List_Protect); + + /* At this point the task is completely built. The ID can now be + set and it can be linked into the created task list. */ + task -> tc_id = TC_TASK_ID; + +#if defined(NU_MODULE_SUPPORT) && (NU_MODULE_SUPPORT > 0) + /* If executing in a thread's context, bind to that thread's module */ + if(TCD_Current_Thread != NU_NULL) + { + status = MSC_Bind_Module_Task( + (MS_MODULE*)(((TC_TCB*)(TCD_Current_Thread))->tc_module), task); + } + else /* It must be initialization time, so use the current module */ + { + status = MSC_Bind_Module_Task(msd_current_module, task); + } +#endif /* NU_MODULE_SUPPORT */ + + /* Link the task into the list of created tasks and increment the + total number of tasks in the system. */ + CSC_Place_On_List(&TCD_Created_Tasks_List, &(task -> tc_created)); + TCD_Total_Tasks++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTask(task,RT_PROF_CREATE_TASK); +#endif + + /* Release the protection. */ + TCT_Unprotect(); + + /* Determine if the task should be automatically started. */ + if (auto_start == NU_START) + { + + /* Protect the system data structures. */ + TCT_Protect(&TCD_System_Protect); + + /* Start the task by resuming it. If the preemption is required, + leave the current task. */ + if (TCC_Resume_Task(task_ptr, NU_PURE_SUSPEND)) + + + /* Transfer control back to the system. */ + TCT_Control_To_System(); + else + + /* Release the protection. */ + TCT_Unprotect(); + } + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return successful completion. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCC_Create_HISR */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function creates a High-Level Interrupt Service Routine */ +/* (HISR) and then places it on the list of created HISRs. All */ +/* the resources necessary to create the HISR are supplied to this */ +/* routine. HISRs are always created in a dormant state. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* TCCE_Create_HISR Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Add TCB to linked-list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCT_Build_HISR_Stack Build an initial HISR stack */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect created HISR list */ +/* TCT_Unprotect Release protection of list */ +/* */ +/* INPUTS */ +/* */ +/* hisr_ptr HISR control block pointer */ +/* name HISR name */ +/* hisr_entry Entry function of the HISR */ +/* priority Task priority */ +/* stack_address Pointer to start of stack */ +/* stack_size Size of HISR stack in bytes */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* added more control block */ +/* initialization, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TCC_Create_HISR(NU_HISR *hisr_ptr, CHAR *name, + VOID (*hisr_entry)(VOID), OPTION priority, + VOID *stack_address, UNSIGNED stack_size) +{ + +R1 TC_HCB *hisr; /* HISR control block ptr */ +R2 INT i; /* Working index variable */ +STATUS status = NU_SUCCESS; + +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input HISR pointer into internal pointer. */ + hisr = (TC_HCB *) hisr_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_CREATE_HISR_ID, (UNSIGNED) hisr, + (UNSIGNED) name, (UNSIGNED) hisr_entry); + +#endif + + /* First, clear the HISR ID just in case it is an old HISR + Control Block. */ + hisr -> tc_id = 0; + + /* Fill in the HISR name. */ + for (i = 0; i < NU_MAX_NAME; i++) + hisr -> tc_name[i] = name[i]; + + /* Fill in the basic HISR information. */ + hisr -> tc_entry = hisr_entry; + hisr -> tc_scheduled = 0; + hisr -> tc_activation_count = 0; + hisr -> tc_cur_time_slice = 0; + + /* Fill in information about the HISR's stack. */ + hisr -> tc_stack_start = stack_address; + hisr -> tc_stack_end = 0; + hisr -> tc_stack_size = stack_size; + hisr -> tc_stack_minimum = stack_size; + + /* Setup priority information for the HISR. Priorities range from 0 to + TC_HISR_PRIORITIES - 1. */ + hisr -> tc_priority = priority & 3; + + /* Initialize link pointers. */ + hisr -> tc_created.cs_previous = NU_NULL; + hisr -> tc_created.cs_next = NU_NULL; + hisr -> tc_active_next = NU_NULL; + + /* Clear protect pointer. */ + hisr -> tc_current_protect = NU_NULL; + + /* Initialize additional kernel options data */ +#if (NU_SUPERV_USER_MODE == 1) + hisr->tc_su_mode = 1; /* TCT_HISR_Shell in Supervisor mode */ + hisr->tc_module = 0; /* Not initially bound to a module */ +#endif + + /* Build a stack frame for this HISR by calling TCT_Build_HISR_Stack. */ + TCT_Build_HISR_Stack(hisr); + + /* Protect the list of created HISRs. */ + TCT_Protect(&TCD_HISR_Protect); + + /* At this point the HISR is completely built. The ID can now be + set and it can be linked into the created HISR list. */ + hisr -> tc_id = TC_HISR_ID; + +#if defined(NU_MODULE_SUPPORT) && (NU_MODULE_SUPPORT > 0) + /* If executing in a thread's context, bind to that thread's module */ + if(TCD_Current_Thread != NU_NULL) + { + status = MSC_Bind_Module_HISR( + (MS_MODULE*)(((TC_TCB*)(TCD_Current_Thread))->tc_module), hisr); + } + else /* It must be initialization time, so use the current module */ + { + status = MSC_Bind_Module_HISR(msd_current_module, hisr); + } +#endif /* NU_MODULE_SUPPORT */ + + /* Link the HISR into the list of created HISRs and increment the + total number of HISRs in the system. */ + CSC_Place_On_List(&TCD_Created_HISRs_List, &(hisr -> tc_created)); + TCD_Total_HISRs++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpHisr(hisr,RT_PROF_CREATE_HISR); +#endif + + /* Release the protection. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return successful completion. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCC_Delete_Task */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function deletes a task and removes it from the list of */ +/* created tasks. It is assumed by this function that the task is */ +/* in a finished or terminated state. Note that this function */ +/* does not free memory associated with the task's control block or */ +/* its stack. This is the responsibility of the application. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* TCCE_Delete_Task Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove node from list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect created task list */ +/* TCT_Unprotect Release protection of list */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Task control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TCC_Delete_Task(NU_TASK *task_ptr) +{ + +R1 TC_TCB *task; /* Task control block ptr */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input task pointer into internal pointer. */ + task = (TC_TCB *) task_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_DELETE_TASK_ID, (UNSIGNED) task, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Protect the list of created tasks. */ + TCT_Protect(&TCD_List_Protect); + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTask(task,RT_PROF_DELETE_TASK); +#endif /*INCLUDE_PROVIEW*/ + + /* Remove the task from the list of created tasks. */ + CSC_Remove_From_List(&TCD_Created_Tasks_List, &(task -> tc_created)); + + /* Decrement the total number of created tasks. */ + TCD_Total_Tasks--; + + /* Clear the task ID just in case. */ + task -> tc_id = 0; + + /* Release protection. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return a successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCC_Delete_HISR */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function deletes a HISR and removes it from the list of */ +/* created HISRs. It is assumed by this function that the HISR is */ +/* in a non-active state. Note that this function does not free */ +/* memory associated with the HISR's control block or its stack. */ +/* This is the responsibility of the application. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* TCCE_Delete_HISR Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove node from list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect created HISR list */ +/* TCT_Unprotect Release protection of list */ +/* */ +/* INPUTS */ +/* */ +/* hisr_ptr HISR control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TCC_Delete_HISR(NU_HISR *hisr_ptr) +{ + +R1 TC_HCB *hisr; /* HISR control block ptr */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input HISR pointer into internal pointer. */ + hisr = (TC_HCB *) hisr_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_DELETE_HISR_ID, (UNSIGNED) hisr, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Protect the list of created HISRs. */ + TCT_Protect(&TCD_HISR_Protect); + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpHisr(hisr,RT_PROF_DELETE_HISR); +#endif /*INCLUDE_PROVIEW*/ + + /* Remove the HISR from the list of created HISRs. */ + CSC_Remove_From_List(&TCD_Created_HISRs_List, &(hisr -> tc_created)); + + /* Decrement the total number of created HISRs. */ + TCD_Total_HISRs--; + + /* Clear the HISR ID just in case. */ + hisr -> tc_id = 0; + + /* Release protection. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return a successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCC_Reset_Task */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function resets the specified task. Note that a task reset */ +/* can only be performed on tasks in a finished or terminated state.*/ +/* The task is left in an unconditional suspended state. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* TCCE_Reset_Task Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCT_Build_Task_Stack Build an initial task stack */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect created task list */ +/* TCT_Unprotect Release protection of list */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Task control block pointer */ +/* argc Optional task parameter */ +/* argv Optional task parameter */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS Indicates successful request */ +/* NU_NOT_TERMINATED Indicates task was not */ +/* finished or terminated */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* added system protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TCC_Reset_Task(NU_TASK *task_ptr, UNSIGNED argc, VOID *argv) +{ + +R1 TC_TCB *task; /* Task control block ptr */ +STATUS status; /* Status of the request */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input task pointer into internal pointer. */ + task = (TC_TCB *) task_ptr; + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_RESET_TASK_ID, (UNSIGNED) task, + (UNSIGNED) argc, (UNSIGNED) argv); + +#endif + + /* Protect system structures. */ + TCT_Protect(&TCD_System_Protect); + + /* Determine if the task is in the proper state. */ + if ((task -> tc_status == NU_FINISHED) || + (task -> tc_status == NU_TERMINATED)) + { + + /* Yes, a valid reset is present. Indicate this in the status. */ + status = NU_SUCCESS; + + /* Fill in the new argument information and reset some of the other + fields. */ + task -> tc_argc = argc; + task -> tc_argv = argv; + task -> tc_status = NU_PURE_SUSPEND; + task -> tc_delayed_suspend = NU_FALSE; + task -> tc_scheduled = 0; + task -> tc_stack_minimum = task -> tc_stack_size; + +#if (NU_SUPERV_USER_MODE == 1) + /* Since we are doing a complete reset we need to ensure + that this field is 0 since the task will be started in + user mode. TCC_Task_Shell can not return and therefore + left the task in supervisor mode when the task completed. + If we were to not re-initialize this field the task would + become locked in user mode and API would fail. */ + task -> tc_su_mode = 0; +#endif + + /* Build a stack frame for this task by calling + TCT_Build_Task_Stack. */ + TCT_Build_Task_Stack(task); + } + else + + /* The requested task is not in a finished or terminated state. */ + status = NU_NOT_TERMINATED; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTask(task,RT_PROF_RESET_TASK); +#endif /*INCLUDE_PROVIEW*/ + + /* Release the protection. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCC_Terminate_Task */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function terminates the specified task. If the task is */ +/* already terminated, this function does nothing. If the task */ +/* to terminate is currently suspended, the specified cleanup */ +/* routine is also invoked to cleanup suspension data structures. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* TCCE_Terminate_Task Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* Cleanup routine Task's suspend cleanup funct */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Suspend_Task Suspend a ready task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect created task list */ +/* TCT_Unprotect Release protection of list */ +/* TCT_Unprotect_Specific Specific unprotection */ +/* TMC_Stop_Task_Timer Stop a task timer */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Task control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* added system protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TCC_Terminate_Task(NU_TASK *task_ptr) +{ + +R1 TC_TCB *task; /* Task control block ptr */ +TC_PROTECT *suspend_protect; /* Suspension protection ptr */ +DATA_ELEMENT status; /* Task status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move task pointer into internal pointer. */ + task = (TC_TCB *) task_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_TERMINATE_TASK_ID, (UNSIGNED) task, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Determine if the calling task is the current task. */ + if (task == (TC_TCB *) TCD_Current_Thread) + { + + /* Protect system data structures. */ + TCT_Protect(&TCD_System_Protect); + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTask(task,RT_PROF_TERMINATE_TASK); +#endif /*INCLUDE_PROVIEW*/ + + /* Suspend the calling task with the NU_TERMINATED status. */ + TCC_Suspend_Task(task_ptr, NU_TERMINATED, NU_NULL, NU_NULL, + NU_SUSPEND); + + /* No need to un-protect, since control never comes back to this + point and the protection is cleared in TCT_Control_To_System. */ + } + else + { + + /* Protect scheduling structures. */ + TCT_Protect(&TCD_System_Protect); + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTask(task,RT_PROF_TERMINATE_TASK); +#endif /*INCLUDE_PROVIEW*/ + + /* Keep trying to terminate the specified task until its status + indicates that it is terminated or finished. */ + while ((task -> tc_status != NU_FINISHED) && + task -> tc_status != NU_TERMINATED) + { + + /* Is the task in a ready state? */ + if (task -> tc_status == NU_READY) + { + + /* Terminate the specified task. */ + TCC_Suspend_Task(task_ptr, NU_TERMINATED, NU_NULL, + NU_NULL,NU_SUSPEND); + + /* Clear system protection. */ + TCT_Unprotect(); + } + else + { + + /* Task is suspended currently. Pickup the suspension + protection. */ + suspend_protect = task -> tc_suspend_protect; + + /* Save the current status. */ + status = task -> tc_status; + + /* Release protection on system structures. */ + TCT_Unprotect(); + + /* Determine if there was a suspension protection. If so + protect it first before the scheduling list protection. + This avoids a deadlock situation. */ + if (suspend_protect) + + /* Protect the terminated task's last suspension + structures. */ + TCT_Protect(suspend_protect); + + /* Protect the system structures again. */ + TCT_Protect(&TCD_System_Protect); + + /* Now determine if the same suspension is in force. */ + if ((task -> tc_status == status) && + (task -> tc_suspend_protect == suspend_protect)) + { + + /* Yes, same suspension is in force. */ + + /* Call cleanup routine, if there is one. */ + if (task -> tc_cleanup) + + /* Call cleanup function. */ + (*(task -> tc_cleanup)) (task -> tc_cleanup_info); + + /* Status the task as terminated. */ + task -> tc_status = NU_TERMINATED; + + /* Determine if there is a timer active. */ + if (task -> tc_timer_active) + { + + /* Call the stop timer function. */ + TMC_Stop_Task_Timer(&(task -> tc_timer_control)); + + /* Clear the timer active flag. */ + task -> tc_timer_active = NU_FALSE; + } + } + + /* Cleanup the protection. */ + if (suspend_protect) + { + + /* Release specific protection. */ + TCT_Unprotect_Specific(suspend_protect); + + /* Clear the suspend protect field. */ + task -> tc_suspend_protect = NU_NULL; + } + + /* Release current protection. */ + TCT_Unprotect(); + } + + /* Protect the scheduling list again. */ + TCT_Protect(&TCD_System_Protect); + } + + /* Release the protection. */ + TCT_Unprotect(); + } + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCC_Resume_Task */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function resumes a previously suspended task. The task */ +/* task must currently be suspended for the same reason indicated */ +/* by this request. If the task resumed is higher priority than */ +/* the calling task and the current task is preemptable, this */ +/* function returns a value of NU_TRUE. Otherwise, if no */ +/* preemption is required, a NU_FALSE is returned. This routine */ +/* must be called from Supervisor mode in a Supervisor/User mode */ +/* switching kernel. */ +/* */ +/* CALLED BY */ +/* */ +/* Other Components */ +/* TCC_Resume_Service Resume service function */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Set_Current_Protect Set current protection field */ +/* TCT_Set_Execute_Task Set TCD_Execute_Task pointer */ +/* TMC_Stop_Task_Timer Stop task timer */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Task control block pointer */ +/* suspend_type Type of suspension to lift */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_TRUE A higher priority task is */ +/* ready to execute */ +/* NU_FALSE No change in the task to */ +/* execute */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 09-19-1993 Corrected an initialization */ +/* problem of de-referencing a */ +/* NULL pointer, resulting in */ +/* version 1.0d */ +/* 09-19-1993 Verified version 1.0d */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* modified protection logic to */ +/* assume that system protection */ +/* is already in force, resulting */ +/* in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 10-29-1997 Changed so that tc_cleanup, */ +/* tc_cleanup_info, and */ +/* tc_suspend_protect are cleared */ +/* only if a signal is not active */ +/* (SPR115) */ +/* 03-20-1998 Corrected SPR455. */ +/* */ +/*************************************************************************/ +STATUS TCC_Resume_Task(NU_TASK *task_ptr, OPTION suspend_type) +{ + +R1 TC_TCB *task; /* Task control block ptr */ +R2 TC_TCB *head; /* Pointer to priority list */ +STATUS status = NU_FALSE; /* Status variable */ + + /* Move task pointer into internal pointer. */ + task = (TC_TCB *) task_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + + /* Check to see if the task is suspended for the reason that this + resume is attempting to clear. */ + if (task -> tc_status == suspend_type) + { + + /* Yes, this resume call is valid. */ + + /* If signals are not active, clear any suspend or cleanup + information (SPR115). */ + if (!task -> tc_signal_active) + { + task -> tc_suspend_protect = NU_NULL; + task -> tc_cleanup = NU_NULL; + task -> tc_cleanup_info = NU_NULL; + } + + /* Determine if there is a timer active and the task is not being + resumed to handle a signal. */ + if ((task -> tc_timer_active) && (!task -> tc_signal_active)) + { + + /* Call the stop timer function. */ + TMC_Stop_Task_Timer(&(task -> tc_timer_control)); + + /* Clear the timer active flag. */ + task -> tc_timer_active = NU_FALSE; + } + + /* Check to see if there is a pending pure suspension. If so, + change the cause of the suspension and leave in a suspended + state. */ + if (task -> tc_delayed_suspend) + { + + /* Leave suspended but change the task's status and clear the + delayed suspension flag. */ + task -> tc_delayed_suspend = NU_FALSE; + task -> tc_status = NU_PURE_SUSPEND; + } + else + { + + /* Lift the suspension of the specified task. */ + + /* Clear the status of the task. */ + task -> tc_status = NU_READY; + +#ifdef INCLUDE_PROVIEW + _RTProf_TaskStatus(task,RT_TASK_READY); +#endif /*INCLUDE_PROVIEW*/ + + /* Link the task into the appropriate priority list. */ + head = *(task -> tc_priority_head); + + /* Determine if the list is non-empty. */ + if (head) + { + + /* Add the new TCB to the end of the ready list. */ + task -> tc_ready_previous = head -> tc_ready_previous; + (task -> tc_ready_previous) -> tc_ready_next = task; + task -> tc_ready_next = head; + (task -> tc_ready_next) -> tc_ready_previous = task; + + /* Note that the priority bit map does not need to be + modified since there are other active tasks at the + same priority. */ + } + else + { + + /* Add the new TCB to an empty list. */ + task -> tc_ready_previous = task; + task -> tc_ready_next = task; + *(task -> tc_priority_head)= task; + + /* Update the priority group bit map to indicate that this + priority now has a task ready. */ + TCD_Priority_Groups = + TCD_Priority_Groups | (task -> tc_priority_group); + + /* Update the sub-priority bit map to show that this priority + is ready. */ + *(task -> tc_sub_priority_ptr) = + (*(task -> tc_sub_priority_ptr)) | task -> tc_sub_priority; + + /* Determine if this newly ready task is higher priority + than the current task. */ + if ((INT) (task -> tc_priority) < TCD_Highest_Priority) + { + + /* Update the highest priority field. */ + TCD_Highest_Priority = (INT) task -> tc_priority; + + /* See if there is a task to execute. */ + if (TCD_Execute_Task == NU_NULL) + + /* Make this task the current. */ + TCT_Set_Execute_Task(task); + + /* Check to see if the task to execute is preemptable. */ + /* SPR455 checks if we are in Application_Initialize */ + else if ((TCD_Execute_Task -> tc_preemption) + || (INC_Initialize_State == INC_START_INITIALIZE)) + { + + /* Yes, the task to execute is preemptable. Replace + it with the new task. */ + TCT_Set_Execute_Task(task); + + /* Now, check and see if the current thread is a task. + If so, return a status that indicates a context + switch is needed. */ + if ((TCD_Current_Thread) && + (((TC_TCB *) TCD_Current_Thread) -> tc_id == + TC_TASK_ID)) + + /* Yes, a context switch is needed. */ + status = NU_TRUE; + } + } + } + } + } + else + { + + /* Check for a resumption of a delayed pure suspend. */ + if (suspend_type == NU_PURE_SUSPEND) + + /* Clear the delayed suspension. */ + task -> tc_delayed_suspend = NU_FALSE; + + /* Check for a signal active and the saved status the same as + the resume request. */ + if ((suspend_type == task -> tc_saved_status) && + (task -> tc_signal_active)) + { + + /* Indicate the saved status as ready. */ + task -> tc_saved_status = NU_READY; + + /* Determine if the task's timer is active. */ + if (task -> tc_timer_active) + { + + /* Stop the timer. */ + TMC_Stop_Task_Timer(&(task -> tc_timer_control)); + + /* Clear the timer active flag. */ + task -> tc_timer_active = NU_FALSE; + } + } + } + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTask(task,RT_PROF_RESUME_TASK); +#endif /*INCLUDE_PROVIEW*/ + + /* Return back the status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCC_Resume_Service */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function provides an interface identical to the application */ +/* service call to resume a task. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* TCCE_Resume_Service Error checking function */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume a task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Protect Protect system structures */ +/* TCT_Unprotect Release system protection */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Task control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS Always returns success */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* added system protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 12-19-1995 Changed the "task" parameter to */ +/* "task_ptr" in the */ +/* HIC_Make_History_Entry call, */ +/* resulting in version 1.1+ */ +/* (SPR 36, 64, 66, 77) */ +/* 10-02-1998 Another protect problem (1.3a) */ +/* */ +/*************************************************************************/ +STATUS TCC_Resume_Service(NU_TASK *task_ptr) +{ + +TC_PROTECT *save_protect; /* Save current protection */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_RESUME_TASK_ID, (UNSIGNED) task_ptr, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Save current protection. */ + if (TCD_Current_Thread != NU_NULL) + { + save_protect = TCT_Get_Current_Protect(); + } + else + { + save_protect = NU_NULL; + } + + /* Protect system structures. */ + TCT_Protect(&TCD_System_Protect); + + /* Call the actual resume task function. If the function returns a + NU_TRUE, context switching is needed. */ + if (TCC_Resume_Task(task_ptr, NU_PURE_SUSPEND)) + { + + /* Transfer control back to the system for a context switch. */ + TCT_Control_To_System(); + } + + /* Determine how to get out of protection. */ + if (save_protect) + { + + /* Restore current protection. */ + TCT_Set_Current_Protect(save_protect); + + /* Release system protect. */ + TCT_Unprotect_Specific(&TCD_System_Protect); + } + else + + /* Release protection of system structures. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Always return a successful status. */ + return(NU_SUCCESS); +} + + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCC_Suspend_Task */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function suspends the specified task. If the specified */ +/* task is the calling task, control is transferred back to the */ +/* system. */ +/* */ +/* CALLED BY */ +/* */ +/* Other Components */ +/* TCC_Suspend_Service Task suspend service */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Protect Protect system structures */ +/* TCT_Set_Execute_Task Set TCD_Execute_Task pointer */ +/* TCT_Protect_Switch Allow protected task to run */ +/* briefly */ +/* TCT_Unprotect Release system protection */ +/* TMC_Start_Task_Timer Start a task timer */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Task control block pointer */ +/* suspend_type Type of suspension to lift */ +/* cleanup Cleanup routine */ +/* information Information for cleanup */ +/* timeout Timeout on the suspension */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 02-01-1994 Corrected a suspension with */ +/* timeout problem that caused */ +/* unconditional task suspension */ +/* for timeouts and sleeps for 1 */ +/* tick, resulting in version 1.0f */ +/* 02-01-1994 Verified version 1.0f */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* fixed a possible suspending an */ +/* executing task from a HISR, */ +/* removed excessive protection */ +/* logic since protection is now */ +/* in force upon function entry, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 06-01-1996 Checked to see whether */ +/* task == TCD_Current_Thread */ +/* regardless of whether task == */ +/* TCD_Execute_Task (SPR152) */ +/* */ +/*************************************************************************/ +VOID TCC_Suspend_Task(NU_TASK *task_ptr, OPTION suspend_type, + VOID (*cleanup) (VOID *), VOID *information, UNSIGNED timeout) +{ + +R1 TC_TCB *task; /* Task control block ptr */ +R2 INT index; /* Working index variable */ +DATA_ELEMENT temp; /* Temporary variable */ + + + + /* Move input task pointer into internal pointer. */ + task = (TC_TCB *) task_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + + /* Determine if there is a timeout to initiate. */ + if (timeout != NU_SUSPEND) + { + + /* Indicate that a task timer is active. */ + task -> tc_timer_active = NU_TRUE; + + /* Start a timeout on the suspension. */ + TMC_Start_Task_Timer(&(task -> tc_timer_control),timeout); + } + + + /* Check for a non self-suspension. In such cases, the target task + cannot have any type of protection in force. */ + if (task != (TC_TCB *) TCD_Current_Thread) + { + + do + { + + /* Check for protection. Remember that system protection is + in effect. */ + if (task -> tc_current_protect) + { + + /* Yes, target task is in a protected mode. Release + the protection on the scheduling list and transfer + control briefly to the target task. */ + TCT_Unprotect(); + + /* Switch to the protected task and wait until the + task is not protected. */ + TCT_Protect_Switch(task); + + /* Restore protection of the system structures. */ + TCT_Protect(&TCD_System_Protect); + } + } while (task -> tc_current_protect); + } + + /* Check to see if the task is currently ready. */ + if (task -> tc_status == NU_READY) + { + + /* Mark the task with the appropriate suspension code. */ + task -> tc_status = suspend_type; + + /* Store off termination information in the tasks control block. */ + task -> tc_cleanup = cleanup; + task -> tc_cleanup_info = information; + + /* Remove the task from the ready list. */ + + /* Determine if the task is the only one on the list. */ + if (task -> tc_ready_next == task) + { + + /* Only task on the list. Clear the task's pointers and + clear the entry in the priority table. */ + task -> tc_ready_next = NU_NULL; + task -> tc_ready_previous = NU_NULL; + *(task -> tc_priority_head) = NU_NULL; + + /* Clear the sub-priority group. */ + *(task -> tc_sub_priority_ptr) = + (*(task -> tc_sub_priority_ptr)) & ~(task -> tc_sub_priority); + + /* Determine if the main priority group needs to be cleared. + This is only true if there are no other bits set in this + sub-priority. */ + if (*(task -> tc_sub_priority_ptr) == 0) + + /* Clear the main priority group bit. */ + TCD_Priority_Groups = + TCD_Priority_Groups & ~(task -> tc_priority_group); + + /* Determine if this priority group was the highest in the + system. */ + if (task -> tc_priority == (DATA_ELEMENT) TCD_Highest_Priority) + { + + /* Determine the highest priority task in the system. */ + if (TCD_Priority_Groups == 0) + { + + /* Re-initialize the highest priority variable and + clear the current task pointer. */ + TCD_Highest_Priority = TC_PRIORITIES; + } + else + { + + /* Find the next highest priority task. */ + if (TCD_Priority_Groups & TC_HIGHEST_MASK) + + /* Base of sub-group is 0. */ + index = 0; + + else if (TCD_Priority_Groups & TC_NEXT_HIGHEST_MASK) + + /* Base of sub-group is 8. */ + index = 8; + + else if (TCD_Priority_Groups & TC_NEXT_LOWEST_MASK) + + /* Base of sub-group is 16. */ + index = 16; + else + + /* Base of sub-group is 24. */ + index = 24; + + /* Calculate the highest available priority. */ + index = index + TCD_Lowest_Set_Bit[(INT) + ((TCD_Priority_Groups >> index) & TC_HIGHEST_MASK)]; + + /* Get the mask of the priority within the group of + 8 priorities. */ + temp = TCD_Sub_Priority_Groups[index]; + + /* Calculate the actual priority. */ + TCD_Highest_Priority = + (index << 3) + TCD_Lowest_Set_Bit[temp]; + } + } + } + else + { + + /* Not the only task ready at the same priority level. */ + + /* Remove from the linked-list. */ + (task -> tc_ready_previous) -> tc_ready_next = + task -> tc_ready_next; + (task -> tc_ready_next) -> tc_ready_previous = + task -> tc_ready_previous; + + /* See if the task being suspended is the current. */ + if (*(task -> tc_priority_head) == task) + + /* Update the head of this priority list. */ + *(task -> tc_priority_head) = task -> tc_ready_next; + + /* Clear the task's pointers. */ + task -> tc_ready_next = NU_NULL; + task -> tc_ready_previous = NU_NULL; + } + + /* Determine if this task the highest priority task. */ + if (task == TCD_Execute_Task) + { + + /* Determine the next task to execute. */ + if (TCD_Highest_Priority < TC_PRIORITIES) + + /* Put the next task to execute in TCD_Execute_Task. */ + TCT_Set_Execute_Task(TCD_Priority_List[TCD_Highest_Priority]); + else + + /* No other task is ready for execution. */ + TCT_Set_Execute_Task(NU_NULL); + } + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTask(task,RT_PROF_SUSPEND_TASK); + + if (suspend_type == NU_SLEEP_SUSPEND) + { + _RTProf_TaskStatus(task,RT_TASK_SLEEPING); + } + else if (suspend_type == NU_PURE_SUSPEND) + { + _RTProf_TaskStatus(task,RT_TASK_SUSPENDED); + } + else + { + _RTProf_TaskStatus(task,RT_TASK_WAITING); + } +#endif /*INCLUDE_PROVIEW*/ + + /* See if the suspending task is the current thread. (SPR152) */ + if (task == (TC_TCB *) TCD_Current_Thread) + + /* Leave the task, transfer control to the system. */ + TCT_Control_To_System(); + + } + else + { + + /* Check for a pure suspension request. If present, the delayed + suspension flag is set. */ + if (suspend_type == NU_PURE_SUSPEND) + + /* Setup the delayed suspension flag. */ + task -> tc_delayed_suspend = NU_TRUE; +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTask(task,RT_PROF_SUSPEND_TASK); +#endif /*INCLUDE_PROVIEW*/ + + } +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCC_Suspend_Service */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function provides a suitable interface to the actual */ +/* service to suspend a task. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* TCCE_Suspend_Service Error checking function */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Suspend_Task Suspend a task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect system structures */ +/* TCT_Unprotect Release system structures */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Task control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS Always a successful status */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* added system protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TCC_Suspend_Service(NU_TASK *task_ptr) +{ + +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_SUSPEND_TASK_ID, (UNSIGNED) task_ptr, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + + /* Protect system data structures. */ + TCT_Protect(&TCD_System_Protect); + + /* Call the actual routine to suspend the task. */ + TCC_Suspend_Task(task_ptr, NU_PURE_SUSPEND, NU_NULL, NU_NULL, NU_SUSPEND); + + /* Release system protection. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Always return a successful status. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCC_Task_Timeout */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processes task suspension timeout conditions. */ +/* Note that task sleep requests are also considered a timeout */ +/* condition. This routine must be called from Supervisor mode in */ +/* a Supervisor/User mode switching kernel. */ +/* */ +/* CALLED BY */ +/* */ +/* TMC_Timer_Task Timer expiration task */ +/* */ +/* CALLS */ +/* */ +/* Caller's cleanup function */ +/* TCC_Resume_Task Resume a suspended task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect scheduling list */ +/* TCT_Set_Current_Protect Setup current protection */ +/* TCT_Unprotect Release protection */ +/* TCT_Unprotect_Specific Release specific protection */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Task control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 02-01-1994 Added logic to clear the timer */ +/* active flag when the target */ +/* task is already in a ready */ +/* state, resulting in */ +/* version 1.0f */ +/* 02-01-1994 Verified version 1.0f */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* removed logic for timeout */ +/* before suspension because new */ +/* protection logic eliminates */ +/* the possibility, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +VOID TCC_Task_Timeout(NU_TASK *task_ptr) +{ + +R1 TC_TCB *task; /* Task control block ptr */ +TC_PROTECT *suspend_protect; /* Suspension protect ptr */ +DATA_ELEMENT task_status; /* Task status variable */ + + + + /* Move task control block pointer into internal pointer. */ + task = (TC_TCB *) task_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Protect system data structures. */ + TCT_Protect(&TCD_System_Protect); + + /* Pickup the suspension protection saved-off when the task was + suspended. */ + suspend_protect = task -> tc_suspend_protect; + + /* Is a signal handler currently running? */ + if (task -> tc_signal_active) + + /* Use the saved status for current task status */ + task_status = task -> tc_saved_status; + else + + /* Just use the current task status */ + task_status = task -> tc_status; + + /* Release protection of the scheduling list. */ + TCT_Unprotect(); + + /* Determine if there is a suspend protect. */ + if (suspend_protect) + + /* Protect the suspended protection. */ + TCT_Protect(suspend_protect); + + /* Now protect the system structures again. Note that the order the + protections are made prevents deadlocks. */ + TCT_Protect(&TCD_System_Protect); + + /* Determine if the task is still suspended in the same manner. */ + if ((task -> tc_status == task_status) || + ((task -> tc_signal_active) && (task -> tc_saved_status == task_status))) + { + + /* Make sure that this timeout processing is still valid. */ + if ((task -> tc_timer_active) && + (task -> tc_timer_control.tm_remaining_time == 0)) + { + + /* Clear the timer active flag. */ + task -> tc_timer_active = NU_FALSE; + + /* Call the cleanup function, if there is one. */ + if (task -> tc_cleanup) + + /* Call cleanup function. */ + (*(task -> tc_cleanup)) (task -> tc_cleanup_info); + + /* Resume the task. */ + TCC_Resume_Task(task_ptr, task_status); + } + } + + /* Determine if a suspend protection was in force. */ + if (suspend_protect) + { + + /* Set the current protection to the suspend protect. */ + TCT_Set_Current_Protect(suspend_protect); + TCT_Unprotect_Specific(&TCD_System_Protect); + } + + /* Release current protection. */ + TCT_Unprotect(); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCC_Task_Sleep */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function provides task sleep suspensions. Its primary */ +/* purpose is to interface with the actual task suspension function.*/ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Suspend_Task Suspend a task */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect system structures */ +/* TCT_Unprotect Release system structures */ +/* */ +/* INPUTS */ +/* */ +/* ticks Number of timer ticks */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified call to suspend the */ +/* calling task, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +VOID TCC_Task_Sleep(UNSIGNED ticks) +{ + +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_SLEEP_ID, (UNSIGNED) ticks, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + + /* Protect system data structures. */ + TCT_Protect(&TCD_System_Protect); + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTask((TC_TCB *)TCD_Current_Thread,RT_PROF_SLEEP); +#endif /*INCLUDE_PROVIEW*/ + + /* Call the actual routine to suspend the task. */ + TCC_Suspend_Task((NU_TASK *) TCD_Current_Thread, NU_SLEEP_SUSPEND, + NU_NULL, NU_NULL, ticks); + + /* Release system protection. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCC_Relinquish */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function moves the calling task to the end of other tasks */ +/* at the same priority level. The calling task does not execute */ +/* again until all the other tasks of the same priority get a */ +/* chance to execute. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* TCCE_Relinquish Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Protect Protect system structures */ +/* TCT_Set_Execute_Task Set TCD_Execute_Task pointer */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +VOID TCC_Relinquish(VOID) +{ + +TC_TCB *task; /* Pointer to task */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_RELINQUISH_ID, (UNSIGNED) 0, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Protect against multiple access to the system structures. */ + TCT_Protect(&TCD_System_Protect); + + /* Pickup the current thread and place it in the task pointer. */ + task = (TC_TCB *) TCD_Current_Thread; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTask(task,RT_PROF_RELINQUISH); +#endif /*INCLUDE_PROVIEW*/ + + /* Determine if another task is ready to run. */ + if ((task -> tc_ready_next != task) || + (task -> tc_priority != (DATA_ELEMENT) TCD_Highest_Priority)) + { + + /* Move the executing task to the end of tasks having the same + priority. */ + *(task -> tc_priority_head) = task -> tc_ready_next; + + /* Setup the next task to execute. */ + TCT_Set_Execute_Task(TCD_Priority_List[TCD_Highest_Priority]); + + /* Transfer control back to the system. */ + TCT_Control_To_System(); + } + + /* Release protection of system structures. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCC_Time_Slice */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function moves the specified task to the end of the other */ +/* tasks at the same priority level. If the specified task is no */ +/* longer ready, this request is ignored. This routine must be */ +/* called from Supervisor mode in a Supervisor/User mode */ +/* switching kernel. */ +/* */ +/* CALLED BY */ +/* */ +/* TMC_Timer_HISR Time-slice interrupt */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect the scheduling data */ +/* TCT_Set_Execute_Task Set TCD_Execute_Task pointer */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* task Task control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* slightly modified protection */ +/* logic, resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +VOID TCC_Time_Slice(NU_TASK *task_ptr) +{ + +R1 TC_TCB *task; /* Task control block ptr */ + + + /* Move input task control block pointer into internal pointer. */ + task = (TC_TCB *) task_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Protect against multiple access to the system structures. */ + TCT_Protect(&TCD_System_Protect); + + /* Determine if another task is ready to run. */ + if (((task -> tc_status == NU_READY) && (task -> tc_preemption)) && + ((task -> tc_ready_next != task) || + (task -> tc_priority != (DATA_ELEMENT) TCD_Highest_Priority))) + { + + /* Move the executing task to the end of tasks having the same + priority. */ + *(task -> tc_priority_head) = task -> tc_ready_next; + + /* Setup the next task to execute. */ + TCT_Set_Execute_Task(TCD_Priority_List[TCD_Highest_Priority]); + + } + + /* Release protection of the system structures. */ + TCT_Unprotect(); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCC_Current_Task_Pointer */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the pointer of the currently executing */ +/* task. If the current thread is not a task thread, a NU_NULL */ +/* is returned. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* Other Components */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* Task Pointer Active tasks pointer or */ +/* NU_NULL if not a task */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +NU_TASK *TCC_Current_Task_Pointer(VOID) +{ + + + /* Determine if a task thread is executing. */ + if ((TCD_Current_Thread) && + (((TC_TCB *) TCD_Current_Thread) -> tc_id == TC_TASK_ID)) + + /* Task thread is running, return the pointer. */ + return((NU_TASK *) TCD_Current_Thread); + else + + /* No, task thread is not running, return a NU_NULL. */ + return(NU_NULL); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCC_Current_HISR_Pointer */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the pointer of the currently executing */ +/* HISR. If the current thread is not a HISR thread, a NU_NULL */ +/* is returned. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* Other Components */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* HISR Pointer Active HISR pointer or */ +/* NU_NULL if not a HISR */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +NU_HISR *TCC_Current_HISR_Pointer(VOID) +{ + + + /* Determine if a HISR thread is executing. */ + if ((TCD_Current_Thread) && + (((TC_HCB *) TCD_Current_Thread) -> tc_id == TC_HISR_ID)) + + /* HISR thread is running, return the pointer. */ + return((NU_HISR *) TCD_Current_Thread); + else + + /* No, HISR thread is not running, return a NU_NULL. */ + return(NU_NULL); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCC_Task_Shell */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is shell from which all application tasks are */ +/* initially executed. The shell causes the task to finish when */ +/* control is returned from the application task. Also, the shell */ +/* passes argc and argv arguments to the task's entry function. */ +/* */ +/* CALLED BY */ +/* */ +/* TCC_Control_To_Task Control to task routine */ +/* */ +/* CALLS */ +/* */ +/* Task Entry Function */ +/* TCC_Suspend_Task Suspend task when finished */ +/* TCT_Protect Protect system structures */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Added protection logic prior to */ +/* suspending the task, resulting */ +/* in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +VOID TCC_Task_Shell(VOID) +{ +NU_SUPERV_USER_VARIABLES + + /* Call the task's entry function with the argc and argv parameters + supplied during task creation or reset. */ + (*(TCD_Execute_Task -> tc_entry)) (TCD_Execute_Task -> tc_argc, + TCD_Execute_Task -> tc_argv); + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Protect system data structures. */ + TCT_Protect(&TCD_System_Protect); + + /* If the task returns, suspend it in a finished state. Note that + the task cannot execute again until it is reset. Therefore, this + call never returns. */ + TCC_Suspend_Task((NU_TASK *) TCD_Execute_Task, NU_FINISHED, + NU_NULL, NU_NULL, NU_SUSPEND); + + /* Return to user mode */ + NU_USER_MODE(); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCC_Signal_Shell */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processes signals by calling the task supplied */ +/* signal handling function. When signal handling is completed, */ +/* the task is placed in the appropriate state. */ +/* */ +/* CALLED BY */ +/* */ +/* TCC_Control_Signals Control task's signals */ +/* TCC_Register_Signal_Handler Register a signal handler */ +/* */ +/* CALLS */ +/* */ +/* task's signal handling routine */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Signal_Exit Signal handling exit routine */ +/* TCT_Protect Protect against other access */ +/* TCT_Set_Execute_Task Set TCD_Execute_Task pointer */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Added register optimizations, */ +/* modified protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +VOID TCC_Signal_Shell(VOID) +{ + +R2 UNSIGNED signals; /* Signals to send to task */ +INT index; /* Working index variable */ +DATA_ELEMENT temp; /* Temporary variable */ +R1 TC_TCB *task; /* Task pointer */ + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Point at the current task. */ + task = (TC_TCB *) TCD_Current_Thread; + + /* Protect against simultaneous access. */ + TCT_Protect(&TCD_System_Protect); + + /* Process while there are signals to handle. */ + while (task -> tc_signals & task -> tc_enabled_signals) + { + + /* Pickup the signals and clear them. */ + signals = task -> tc_signals; + task -> tc_signals = 0; + + /* Release protection. */ + TCT_Unprotect(); + + /* Call the application signal handling function, if there still is + one. */ + if (task -> tc_signal_handler) + { + NU_SUPERV_USER_VARIABLES + +#if (defined(NU_SUPERV_USER_MODE)) && (NU_SUPERV_USER_MODE > 0) + UNSIGNED savedMode = task->tc_su_mode; + task->tc_su_mode = 1; /* Force transition to User mode */ +#endif + /* Switch to user mode */ + NU_USER_MODE(); + + /* Call signal handler. (always in User mode) */ + (*(task -> tc_signal_handler))(signals); + + /* Return to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#if (defined(NU_SUPERV_USER_MODE)) && (NU_SUPERV_USER_MODE > 0) + task->tc_su_mode = savedMode; /* Restore original nesting count */ +#endif + } + + /* Protect against simultaneous access again. */ + TCT_Protect(&TCD_System_Protect); + } + + /* At this point, signals have been exhausted and protection is in + force. */ + + /* Clear the signal in process flag. */ + task -> tc_signal_active = NU_FALSE; + + /* Determine how the signal handler was called. Either in a solicited or + an unsolicited manner. */ + if (task -> tc_saved_stack_ptr) + { + + /* Determine if the saved status still indicates that the task should + be suspended. */ + if (task -> tc_saved_status != NU_READY) + { + + /* Suspend the task. */ + task -> tc_status = task -> tc_saved_status; + + /* Remove the task from the ready list. */ + + /* Determine if the task is the only one on the list. */ + if (task -> tc_ready_next == task) + { + + /* Only task on the list. Clear the task's pointers and + clear the entry in the priority table. */ + task -> tc_ready_next = NU_NULL; + task -> tc_ready_previous = NU_NULL; + *(task -> tc_priority_head) = NU_NULL; + + /* Clear the sub-priority group. */ + *(task -> tc_sub_priority_ptr) = + (*(task -> tc_sub_priority_ptr)) & ~(task -> tc_sub_priority); + + /* Determine if the main priority group needs to be cleared. + This is only true if there are no other bits set in this + sub-priority. */ + if (*(task -> tc_sub_priority_ptr) == 0) + + /* Clear the main priority group bit. */ + TCD_Priority_Groups = + TCD_Priority_Groups & ~(task -> tc_priority_group); + + /* Determine if this priority group was the highest in the + system. */ + if (task -> tc_priority == (DATA_ELEMENT) TCD_Highest_Priority) + { + + /* Determine the highest priority task in the system. */ + if (TCD_Priority_Groups == 0) + { + + /* Re-initialize the highest priority variable and + clear the current task pointer. */ + TCD_Highest_Priority = TC_PRIORITIES; + } + else + { + + /* Find the next highest priority task. */ + if (TCD_Priority_Groups & TC_HIGHEST_MASK) + + /* Base of sub-group is 0. */ + index = 0; + + else if (TCD_Priority_Groups & TC_NEXT_HIGHEST_MASK) + + /* Base of sub-group is 8. */ + index = 8; + + else if (TCD_Priority_Groups & TC_NEXT_LOWEST_MASK) + + /* Base of sub-group is 16. */ + index = 16; + else + + /* Base of sub-group is 24. */ + index = 24; + + /* Calculate the highest available priority. */ + index = index + TCD_Lowest_Set_Bit[(INT) + ((TCD_Priority_Groups >> index) & TC_HIGHEST_MASK)]; + + /* Get the mask of the priority within the group of + 8 priorities. */ + temp = TCD_Sub_Priority_Groups[index]; + + /* Calculate the actual priority. */ + TCD_Highest_Priority = + (index << 3) + TCD_Lowest_Set_Bit[temp]; + } + } + } + else + { + + /* Not the only task ready at the same priority level. */ + + /* Remove from the linked-list. */ + (task -> tc_ready_previous) -> tc_ready_next = + task -> tc_ready_next; + (task -> tc_ready_next) -> tc_ready_previous = + task -> tc_ready_previous; + + /* See if the task being suspended is the current. */ + if (*(task -> tc_priority_head) == task) + + /* Update the head of this priority list. */ + *(task -> tc_priority_head) = task -> tc_ready_next; + + /* Clear the task's pointers. */ + task -> tc_ready_next = NU_NULL; + task -> tc_ready_previous = NU_NULL; + } + + /* Determine the next task to execute. */ + if (TCD_Highest_Priority < TC_PRIORITIES) + + /* Put the next task to execute in TCD_Execute_Task. */ + TCT_Set_Execute_Task(TCD_Priority_List[TCD_Highest_Priority]); + else + + /* No other task is ready for execution. */ + TCT_Set_Execute_Task(NU_NULL); + } + + /* At this point, just exit back to the system. Note that the + signal exit routine clears the scheduling protection. */ + TCT_Signal_Exit(); + } + + /* A signal handler was called from the current task. Nothing needs + to be done except to release protection. */ + TCT_Unprotect(); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCC_Dispatch_LISR */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function dispatches the LISR associated with the specified */ +/* interrupt vector. Note that this function is called during */ +/* the interrupt thread. This routine must be called from */ +/* Supervisor mode in a Supervisor/User mode switching kernel. */ +/* */ +/* CALLED BY */ +/* */ +/* INT_Interrupt_Shell Shell of interrupt routine */ +/* */ +/* CALLS */ +/* */ +/* application LISR */ +/* ERC_System_Error Unhandled interrupt error */ +/* */ +/* INPUTS */ +/* */ +/* vector Vector number of interrupt */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 11-01-1993 Added logic to save unhandled */ +/* interrupt vector number in */ +/* a global variable, resulting */ +/* in version 1.0e */ +/* 11-01-1993 Verified version 1.0e */ +/* */ +/*************************************************************************/ +VOID TCC_Dispatch_LISR(INT vector) +{ + +INT index; /* Working index variable */ + + + /* Determine if the specified vector has an LISR registered to it. */ + index = (INT) TCD_Registered_LISRs[vector]; + if (index <= NU_MAX_LISRS) + { +#ifdef INCLUDE_PROVIEW + _RTProf_Dispatch_LISR_No_INT_Lock(vector); +#endif /*INCLUDE_PROVIEW*/ + + /* Yes, an LISR is associated with this vector. Call the actual + registered LISR routine. */ + (*(TCD_LISR_Pointers[index])) (vector); + } + else + { + + /* Save interrupt vector number in TCD_Unhandled_Interrupt. */ + TCD_Unhandled_Interrupt = vector; + + /* System error, unhandled interrupt. */ + ERC_System_Error(NU_UNHANDLED_INTERRUPT); + } +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCC_Register_LISR */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function registers the supplied LISR with the supplied */ +/* vector number. If the supplied LISR is NU_NULL, the supplied */ +/* vector is de-registered. The previously registered LISR is */ +/* returned to the caller, along with the completion status. This */ +/* routine must be called from Supervisor mode in a Supervisor/ */ +/* User mode switching kernel. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* INT_Retrieve_Shell Retrieve vector shell pointer*/ +/* INT_Setup_Vector Setup the actual vector */ +/* INT_Vectors_Loaded Determine if interrupt shell */ +/* routines are loaded */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect LISR registration */ +/* TCT_Unprotect Release LISR protection */ +/* */ +/* INPUTS */ +/* */ +/* vector Vector number of interrupt */ +/* new_lisr New LISR function */ +/* old_lisr Previous LISR function ptr */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS Successful registration */ +/* NU_INVALID_VECTOR Invalid interrupt vector */ +/* NU_NO_MORE_LISRS LISR registration table is */ +/* full */ +/* NU_NOT_REGISTERED LISR was not registered */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Added appropriate casting, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TCC_Register_LISR(INT vector, VOID (*new_lisr)(INT), + VOID (**old_lisr)(INT)) +{ + +INT index; /* Working index variable */ +STATUS status; /* Completion status */ + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_REGISTER_LISR_ID, (UNSIGNED) vector, + (UNSIGNED) new_lisr, (UNSIGNED) old_lisr); + +#endif + + /* Determine if the vector is legal. */ + if (vector > NU_MAX_VECTORS) + return(NU_INVALID_VECTOR); + + /* Initialize the completion status to successful. */ + status = NU_SUCCESS; + + /* Protect against LISR registration list access. */ + TCT_Protect(&TCD_LISR_Protect); + + /* Determine if a registration or deregistration is requested. This is + determined by the value of new_lisr. A NULL value indicates + deregistration. */ + if (new_lisr) + { + + /* Register the new LISR. */ + + /* Determine if the vector already has a registration. */ + if (TCD_Registered_LISRs[vector]) + { + + /* Yes, a registration exists. */ + + /* Pickup the index into the LISR pointer list. */ + index = (INT) TCD_Registered_LISRs[vector]; + + /* Temporarily indicate that the LISR is not registered. */ + TCD_Registered_LISRs[vector] = 0; + + /* Copy the currently registered LISR into the old_lisr return + area. */ + *old_lisr = TCD_LISR_Pointers[index]; + + /* Place the new LISR into the list. */ + TCD_LISR_Pointers[index] = new_lisr; + + /* Indicate the LISR is registered again. */ + TCD_Registered_LISRs[vector] = (UNSIGNED_CHAR) index; + } + else + { + + /* An empty slot needs to be found in the LISR pointers list. */ + + index = 0; + while ((index <= NU_MAX_LISRS) && + (TCD_LISR_Pointers[index] != NU_NULL)) + index++; + + /* Determine if an empty slot was found. */ + if (index <= NU_MAX_LISRS) + { + + /* Yes, an empty slot was found. */ + + /* Place the new LISR in the LISR pointers list. */ + TCD_LISR_Pointers[index] = new_lisr; + + /* Associate the index into the pointers list to the actual + vector. */ + TCD_Registered_LISRs[vector] = (UNSIGNED_CHAR) index; + + /* Indicate that there was no previous LISR registered. */ + *old_lisr = NU_NULL; + + /* Determine if the actual vector needs to be stolen. */ + if (!INT_Vectors_Loaded()) + + /* Actual vector needs to be replaced with the + appropriate ISR shell. */ + INT_Setup_Vector(vector, INT_Retrieve_Shell(vector)); + } + else + + /* Return the completion status that indicates that there + is no more room in the LISR pointers list. */ + status = NU_NO_MORE_LISRS; + } + } + else + { + + /* De-register the specified vector. */ + + /* Determine if the vector has a registration current. */ + if (TCD_Registered_LISRs[vector]) + { + + /* Pickup the index into the LISR pointer list. */ + index = (INT) TCD_Registered_LISRs[vector]; + + /* Clear the registration table. */ + TCD_Registered_LISRs[vector] = 0; + + /* Return the previously registered LISR. */ + *old_lisr = TCD_LISR_Pointers[index]; + + /* Clear the LISR pointer list entry. */ + TCD_LISR_Pointers[index] = NU_NULL; + } + else + + /* The vector is not registered. Return an error completion + status. */ + status = NU_NOT_REGISTERED; + } + +#ifdef INCLUDE_PROVIEW + _RTProf_RegisterLisr(vector); +#endif /*INCLUDE_PROVIEW*/ + + /* Release protection on the LISR registration list. */ + TCT_Unprotect(); + + /* Return the completion status. */ + return(status); +} + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/tcce.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,1134 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* tcce.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* TC - Thread Control */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains error checking routines for the functions in */ +/* the Thread Control component. This permits easy removal of */ +/* error checking logic when it is not needed. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* TCCE_Create_Task Create a task */ +/* TCCE_Create_HISR Create HISR */ +/* TCCE_Delete_HISR Delete HISR */ +/* TCCE_Delete_Task Delete a task */ +/* TCCE_Reset_Task Reset a task */ +/* TCCE_Terminate_Task Terminate a task */ +/* TCCE_Resume_Service Resume a task service call */ +/* TCCE_Suspend_Service Suspend a task service call */ +/* TCCE_Relinquish Relinquish task execution */ +/* TCCE_Task_Sleep Task sleep request */ +/* TCCE_Suspend_Error Check for suspend req error */ +/* TCCE_Activate_HISR Activate an HISR */ +/* TCCE_Validate_Resume Validates resume requests */ +/* */ +/* DEPENDENCIES */ +/* */ +/* tc_extr.h Thread Control functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified logic that checked task */ +/* status without protection of */ +/* scheduling structures, */ +/* resulting in version 1.0a */ +/* 03-01-1994 Verified version 1.0a */ +/* 03-01-1994 Moved non-core error checking */ +/* functions to a supplemental */ +/* file, and modified function */ +/* interfaces, added validate */ +/* resume service, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 03-19-1996 Added error checking to */ +/* TCCE_Task_Sleep, resulting */ +/* in version 1.1+ (spr037) */ +/* 04-17-1996 updated to version 1.2 */ +/* 10-16-1996 Modified to save the current */ +/* thread's protection rather */ +/* than that of the task being */ +/* resumed (SPR212)(SPR268) */ +/* 03-24-1998 Released version 1.3. */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "tc_extr.h" /* Thread control functions */ + +/* Define external inner-component global data references. */ + +extern TC_TCB *TCD_Execute_Task; +extern VOID *TCD_Current_Thread; + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCCE_Create_Task */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the create task function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCC_Create_Task Actual create task function */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Task control block pointer */ +/* name Task name */ +/* task_entry Entry function of the task */ +/* argc Optional task parameter */ +/* argv Optional task parameter */ +/* stack_address Pointer to start of stack */ +/* stack_size Size of task stack in bytes */ +/* priority Task priority */ +/* time_slice Task time slice */ +/* preempt Task preemptability flag */ +/* auto_start Automatic task start */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS Successful request */ +/* NU_INVALID_TASK Task control block pointer */ +/* is NULL */ +/* NU_INVALID_ENTRY Task entry function is NULL */ +/* NU_INVALID_MEMORY Stack pointer is NULL */ +/* NU_INVALID_SIZE Stack size is too small */ +/* NU_INVALID_PRIORITY Invalid task priority */ +/* NU_INVALID_PREEMPT Invalid preemption selection */ +/* NU_INVALID_START Invalid start selection */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TCCE_Create_Task(NU_TASK *task_ptr, CHAR *name, + VOID (*task_entry)(UNSIGNED, VOID *), UNSIGNED argc, VOID *argv, + VOID *stack_address, UNSIGNED stack_size, + OPTION priority, UNSIGNED time_slice, + OPTION preempt, OPTION auto_start) +{ + +TC_TCB *task; /* Task control block ptr */ +STATUS status; /* Completion status */ + + + /* Move input task control block pointer into internal pointer. */ + task = (TC_TCB *) task_ptr; + + /* Check each parameter. */ + if ((task == NU_NULL) || (task -> tc_id == TC_TASK_ID)) + + /* Invalid task control block pointer. */ + status = NU_INVALID_TASK; + + else if (task_entry == NU_NULL) + + /* Invalid task entry function pointer. */ + status = NU_INVALID_ENTRY; + + else if (stack_address == NU_NULL) + + /* Invalid stack starting address. */ + status = NU_INVALID_MEMORY; + + else if (stack_size < NU_MIN_STACK_SIZE) + + /* Invalid stack size. */ + status = NU_INVALID_SIZE; + + + else if ((preempt != NU_PREEMPT) && (preempt != NU_NO_PREEMPT)) + + /* Invalid preemption. */ + status = NU_INVALID_PREEMPT; + + else if ((auto_start != NU_START) && (auto_start != NU_NO_START)) + + /* Invalid start selection. */ + status = NU_INVALID_START; + + else + + /* Call the actual function to create a task. All the parameters + appear to be correct. */ + status = TCC_Create_Task(task_ptr, name, task_entry, argc, argv, + stack_address, stack_size, priority, time_slice, preempt, auto_start); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCCE_Create_HISR */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the create HISR function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCC_Create_HISR Actual create HISR function */ +/* */ +/* INPUTS */ +/* */ +/* hisr_ptr HISR control block pointer */ +/* name HISR name */ +/* hisr_entry Entry function of the HISR */ +/* priority Task priority */ +/* stack_address Pointer to start of stack */ +/* stack_size Size of HISR stack in bytes */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_HISR Invalid HISR pointer */ +/* NU_INVALID_ENTRY Invalid HISR entry point */ +/* NU_INVALID_PRIORITY Invalid HISR priority */ +/* NU_INVALID_MEMORY Indicates stack pointer NULL */ +/* NU_INVALID_SIZE Indicates stack size is too */ +/* small */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TCCE_Create_HISR(NU_HISR *hisr_ptr, CHAR *name, + VOID (*hisr_entry)(VOID), OPTION priority, + VOID *stack_address, UNSIGNED stack_size) +{ + +TC_HCB *hisr; /* HISR control block ptr */ +STATUS status; /* Completion status */ + + + + /* Move input HISR pointer into internal pointer. */ + hisr = (TC_HCB *) hisr_ptr; + + /* Check each parameter. */ + if ((hisr == NU_NULL) || (hisr -> tc_id == TC_HISR_ID)) + + /* Invalid HISR control block pointer. */ + status = NU_INVALID_HISR; + + else if (hisr_entry == NU_NULL) + + /* Invalid HISR entry function pointer. */ + status = NU_INVALID_ENTRY; + + else if (stack_address == NU_NULL) + + /* Invalid stack starting address. */ + status = NU_INVALID_MEMORY; + + else if (stack_size < NU_MIN_STACK_SIZE) + + /* Invalid stack size. */ + status = NU_INVALID_SIZE; + + else if (((INT) priority) >= TC_HISR_PRIORITIES) + + /* Invalid HISR priority. */ + status = NU_INVALID_PRIORITY; + + else + + /* Call the actual function to create a HISR. All the parameters + appear to be correct. */ + status = TCC_Create_HISR(hisr_ptr, name, hisr_entry, priority, + stack_address, stack_size); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCCE_Delete_Task */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the delete task function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCC_Delete_Task Actual delete task function */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Task control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If successful completion */ +/* NU_INVALID_TASK Task pointer is invalid */ +/* NU_INVALID_DELETE Task not in a finished or */ +/* terminated state */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TCCE_Delete_Task(NU_TASK *task_ptr) +{ + +TC_TCB *task; /* Task control block ptr */ +STATUS status; /* Completion status */ + + + /* Move input task control block pointer into internal pointer. */ + task = (TC_TCB *) task_ptr; + + /* Determine if the supplied task pointer is valid. */ + if ((task == NU_NULL) || (task -> tc_id != TC_TASK_ID)) + + /* Invalid task pointer supplied. */ + status = NU_INVALID_TASK; + + else if ((task -> tc_status != NU_FINISHED) && + (task -> tc_status != NU_TERMINATED)) + + /* A task that is not in the finished or terminated state cannot + be deleted. */ + status = NU_INVALID_DELETE; + + else + + /* Valid task pointer, call the function to delete the task. */ + status = TCC_Delete_Task(task_ptr); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCCE_Delete_HISR */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the delete HISR function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCC_Delete_HISR Actual delete HISR function */ +/* */ +/* INPUTS */ +/* */ +/* hisr_ptr HISR control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_HISR Indicates HISR pointer is */ +/* invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TCCE_Delete_HISR(NU_HISR *hisr_ptr) +{ + +TC_HCB *hisr; /* HISR control block ptr */ +STATUS status; /* Completion status */ + + + /* Move input HISR control block pointer into internal pointer. */ + hisr = (TC_HCB *) hisr_ptr; + + /* Determine if the supplied HISR pointer is valid. */ + if ((hisr) && (hisr -> tc_id == TC_HISR_ID)) + + /* Valid HISR pointer, call the function to delete the HISR. */ + status = TCC_Delete_HISR(hisr_ptr); + else + + /* Invalid HISR pointer, indicate with the status. */ + status = NU_INVALID_HISR; + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCCE_Reset_Task */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the reset task function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCC_Reset_Task Actual reset task function */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Task control block pointer */ +/* argc Optional task parameter */ +/* argv Optional task parameter */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_TASK Indicates task pointer is */ +/* invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TCCE_Reset_Task(NU_TASK *task_ptr, UNSIGNED argc, VOID *argv) +{ + +TC_TCB *task; /* Task control block ptr */ +STATUS status; /* Status of the request */ + + + /* Move input task control block pointer into internal pointer. */ + task = (TC_TCB *) task_ptr; + + /* Determine if the task pointer is valid. */ + if ((task == NU_NULL) || (task -> tc_id != TC_TASK_ID)) + + /* Task pointer is invalid. */ + status = NU_INVALID_TASK; + else + + /* Call actual function to reset the task. */ + status = TCC_Reset_Task(task_ptr, argc, argv); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCCE_Terminate_Task */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the terminate task function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCC_Terminate_Task Actual terminate task funct */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Task control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_TASK Indicates task pointer is */ +/* invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TCCE_Terminate_Task(NU_TASK *task_ptr) +{ + +TC_TCB *task; /* Task control block ptr */ +STATUS status; /* Status return */ + + + /* Move input task control block pointer into internal pointer. */ + task = (TC_TCB *) task_ptr; + + /* Determine if the task pointer is valid. */ + if ((task == NU_NULL) || (task -> tc_id != TC_TASK_ID)) + + /* Task pointer is invalid. */ + status = NU_INVALID_TASK; + else + + /* Call actual function to terminate the task. */ + status = TCC_Terminate_Task(task_ptr); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCCE_Resume_Service */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the resume task function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCCE_Validate_Resume Function that checks the */ +/* current task status for a */ +/* valid resume request */ +/* TCC_Resume_Service Actual task resume service */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Task control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If successful completion */ +/* NU_INVALID_TASK Task pointer is invalid */ +/* NU_INVALID_RESUME Not previously suspended */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified logic that checked task */ +/* status without protection of */ +/* scheduling structures, */ +/* resulting in version 1.0a */ +/* 03-01-1994 Verified version 1.0a */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* moved validate resume function */ +/* to this file, resulting in */ +/* version 1.1 */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TCCE_Resume_Service(NU_TASK *task_ptr) +{ + +TC_TCB *task; /* Task control block ptr */ +STATUS status; /* Completion status */ + + + + /* Move task control block pointer into internal pointer. */ + task = (TC_TCB *) task_ptr; + + /* Determine if the task pointer is valid. */ + if ((task == NU_NULL) || (task -> tc_id != TC_TASK_ID)) + + /* Task pointer is invalid. */ + status = NU_INVALID_TASK; + + /* Make sure that the task is suspended in an identical manner. */ + else if (TCCE_Validate_Resume(NU_PURE_SUSPEND, task_ptr)) + + /* Task is not unconditionally suspended, return error status. */ + status = NU_INVALID_RESUME; + + else + + /* Call the actual resume service. */ + status = TCC_Resume_Service(task_ptr); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCCE_Suspend_Service */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the suspend service. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCC_Suspend_Service Actual suspend service */ +/* function */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Task control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If successful completion */ +/* NU_INVALID_TASK Task pointer is invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TCCE_Suspend_Service(NU_TASK *task_ptr) +{ + +TC_TCB *task; /* Task control block ptr */ +STATUS status; /* Completion status */ + + + + /* Move task control block pointer into internal pointer. */ + task = (TC_TCB *) task_ptr; + + /* Determine if the task pointer is valid. */ + if ((task == NU_NULL) || (task -> tc_id != TC_TASK_ID)) + + /* Task pointer is invalid. */ + status = NU_INVALID_TASK; + + else + + if ((task->tc_status == NU_FINISHED) || (task->tc_status == NU_TERMINATED)) + + /* Can't suspend a task in a finished or terminated state */ + status = NU_INVALID_SUSPEND; + + + else + + /* Call the actual service routine. */ + status = TCC_Suspend_Service(task_ptr); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCCE_Relinquish */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking for the relinquish */ +/* function. If the current thread is not a task, this request */ +/* is ignored. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCC_Relinquish Actual relinquish function */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +VOID TCCE_Relinquish(VOID) +{ + +TC_TCB *task; /* Pointer to task */ + + /* Pickup the current thread and place it in the task pointer. */ + task = (TC_TCB *) TCD_Current_Thread; + + /* Determine if the current thread is a task. If so, call the actual + relinquish routine. Otherwise, ignore the request. */ + if ((task) && (task -> tc_id == TC_TASK_ID)) + + /* Valid request, call the relinquish function. */ + TCC_Relinquish(); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCCE_Task_Sleep */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking for the task sleep */ +/* function. If the current thread is not a task, this request */ +/* is ignored. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCC_Task_Sleep Actual task sleep function */ +/* */ +/* INPUTS */ +/* */ +/* ticks Number of ticks to sleep for */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-19-1996 Added check for parameter of 0 */ +/* or negative number, resulting */ +/* in version 1.1+ (spr037) */ +/* */ +/*************************************************************************/ +VOID TCCE_Task_Sleep(UNSIGNED ticks) +{ + +TC_TCB *task; /* Pointer to task */ + + /* If parameter is zero, return */ + if (ticks == 0) + return; + + /* Pickup the current thread and place it in the task pointer. */ + task = (TC_TCB *) TCD_Current_Thread; + + /* Determine if the current thread is a task. If so, call the actual + task sleep routine. Otherwise, ignore the request. */ + if ((task) && (task -> tc_id == TC_TASK_ID)) + + /* Valid request, call the sleep function. */ + TCC_Task_Sleep(ticks); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCCE_Suspend_Error */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function checks for a suspend request error. Suspension */ +/* requests are only allowed from task threads. A suspend request */ +/* from any other thread is an error. */ +/* */ +/* CALLED BY */ +/* */ +/* Other Components */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_TRUE If an error is detected */ +/* NU_FALSE If no error is detected */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +INT TCCE_Suspend_Error(VOID) +{ + +TC_TCB *task; /* Task pointer */ +INT status = NU_FALSE; /* Initialize to no error */ + + + /* Setup the task pointer. */ + task = (TC_TCB *) TCD_Current_Thread; + + /* Check for suspension errors. */ + if (task == NU_NULL) + + /* Error, suspend request probably from initialization. */ + status = NU_TRUE; + + else if (task -> tc_id != TC_TASK_ID) + + /* Control block is probably an HISR not a task. */ + status = NU_TRUE; + + else if (task -> tc_signal_active) + + /* Called from a signal handler. */ + status = NU_TRUE; + + /* Return status to caller. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCCE_Activate_HISR */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the activate HISR function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCT_Activate_HISR Actual HISR activate call */ +/* */ +/* INPUTS */ +/* */ +/* hisr_ptr HISR control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_HISR Invalid HISR pointer */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TCCE_Activate_HISR(NU_HISR *hisr_ptr) +{ + +TC_HCB *hisr; /* HISR control block ptr */ +STATUS status; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + NU_SUPERVISOR_MODE(); + /* Move input HISR control block pointer into internal pointer. */ + hisr = (TC_HCB *) hisr_ptr; + + /* Check each parameter. */ + if (hisr == NU_NULL) + + /* Invalid HISR control block pointer. */ + status = NU_INVALID_HISR; + + else if (hisr -> tc_id != TC_HISR_ID) + + /* Invalid HISR control block pointer. */ + status = NU_INVALID_HISR; + + else + + /* Call the routine to activate the HISR. */ + status = TCT_Activate_HISR(hisr_ptr); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCCE_Validate_Resume */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function validates the resume service and resume driver */ +/* calls with scheduling protection around the examination of the */ +/* task status. */ +/* */ +/* CALLED BY */ +/* */ +/* IOCE_Resume_Driver Driver error checking funct. */ +/* TCCE_Resume_Service Error checking function */ +/* */ +/* CALLS */ +/* */ +/* TCT_Set_Current_Protect Setup current protect pointer*/ +/* TCT_System_Protect Protect from system access */ +/* TCT_System_Unprotect Release system protection */ +/* TCT_Unprotect Release current protection */ +/* */ +/* INPUTS */ +/* */ +/* resume_type Type of resume request */ +/* task_ptr Task control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_TRUE Invalid resume */ +/* NU_FALSE Valid resume */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Created initial version of */ +/* function for version 1.0g */ +/* 03-01-1994 Verified version 1.0g */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* added system protection logic, */ +/* moved to TCCE since it is an */ +/* error interface function, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 10-16-1996 Modified to save the current */ +/* thread's protection rather */ +/* than that of the task being */ +/* resumed (SPR212)(SPR268) */ +/* */ +/*************************************************************************/ +STATUS TCCE_Validate_Resume(OPTION resume_type, NU_TASK *task_ptr) +{ + +R1 TC_TCB *task; /* Task control block ptr */ +TC_PROTECT *save_protect; /* Save current protection */ +STATUS status; /* Return status variable */ +NU_SUPERV_USER_VARIABLES + + NU_SUPERVISOR_MODE(); + + /* Move input task pointer into internal pointer. */ + task = (TC_TCB *) task_ptr; + + /* Save current protection. */ + if (TCD_Current_Thread != NU_NULL) + { + save_protect = TCT_Get_Current_Protect(); + } + else + { + save_protect = NU_NULL; + } + + /* Protect the scheduling structures from multiple access. */ + TCT_System_Protect(); + + /* Does the resume type match the current status? */ + if (task -> tc_status == resume_type) + + /* Indicate that there is no error. */ + status = NU_FALSE; + + /* Check for a resumption of a delayed pure suspend. */ + else if ((resume_type == NU_PURE_SUSPEND) && (task -> tc_delayed_suspend)) + + /* Indicate that there is no error. */ + status = NU_FALSE; + + /* Check for a signal active and the saved status the same as + the resume request. */ + else if ((resume_type == task -> tc_saved_status) && + (task -> tc_signal_active)) + + /* Indicate that there is no error. */ + status = NU_FALSE; + + else + + /* Indicate that there is an error. */ + status = NU_TRUE; + + /* Determine how to get out of protection. */ + if (save_protect) + { + + /* Restore current protection. */ + TCT_Set_Current_Protect(save_protect); + + /* Release system protect. */ + TCT_System_Unprotect(); + } + else + + /* Release protection of system structures. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return status to caller. */ + return(status); +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/tcd.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,300 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* tcd.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* TC - Thread Control */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains global data structures for use within this */ +/* component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* TCD_Created_Tasks_List Pointer to the linked-list */ +/* of created tasks */ +/* TCD_Total_Tasks Total number of created tasks*/ +/* TCD_Priority_List Array of pointers to ready */ +/* tasks, indexed by priority */ +/* TCD_Execute_Task Highest priority task to */ +/* execute */ +/* TCD_Priority_Groups Bit map of 32 groups of task */ +/* priority */ +/* TCD_Sub_Priority_Groups An array of 32 sub-priority */ +/* groups */ +/* TCD_Lowest_Set_Bit Lookup table to find the */ +/* lowest bit set in a byte */ +/* TCD_Highest_Priority Highest priority ready */ +/* TCD_Created_HISRs_List Pointer to the linked-list */ +/* of created HISRs */ +/* TCD_Total_HISRs Total number of created HISRs*/ +/* TCD_Active_HISR_Heads Active HISR list head ptrs */ +/* TCD_Active_HISR_Tails Active HISR list tail ptrs */ +/* TCD_Execute_HISR Highest priority HISR to */ +/* execute */ +/* TCD_Current_Thread Pointer to the currently */ +/* executing thread */ +/* TCD_Registered_LISRs List of registered LISRs */ +/* TCD_LISR_Pointers Actual LISR pointers */ +/* TCD_Interrupt_Count Count of ISRs in progress */ +/* TCD_Stack_Switched Flag indicating that stack */ +/* was switched in an ISR */ +/* TCD_List_Protect Task list protection */ +/* TCD_System_Protect System protection */ +/* TCD_System_Stack System stack pointer - top */ +/* TCD_LISR_Protect Protect LISR registration */ +/* TCD_HISR_Protect Protect the list of created */ +/* HISRs */ +/* TCD_Interrupt_Level Enable interrupt level */ +/* TCD_Unhandled_Interrupt Contains the most recent */ +/* unhandled interrupt in */ +/* system error conditions */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_defs.h Common Service constants */ +/* tc_defs.h Thread Control constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 01-01-1993 Added variable to save last */ +/* unhandled interrupt in system */ +/* error conditions, resulting in */ +/* version 1.0a */ +/* 11-01-1993 Verified version 1.0a */ +/* 03-01-1994 Change schedule protection to a */ +/* system protection to improve */ +/* performance, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-23-2001 Made TCD_LISR_Pointers array an exclusive count */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + +#include "cs_defs.h" /* Common Service constants */ +#include "tc_defs.h" /* Thread Control constants */ + + +/* TCD_Created_Tasks_List is the head pointer of the linked list of + created tasks. If the list is NU_NULL, there are no tasks created. */ + +CS_NODE *TCD_Created_Tasks_List; + + +/* TCD_Total_Tasks contains the number of currently created tasks. */ + +UNSIGNED TCD_Total_Tasks; + + +/* TCD_Priority_List is an array of TCB pointers. Each element of the array + is effectively the head pointer of the list of tasks ready for execution + at that priority. If the pointer is NULL, there are no tasks ready + for execution at that priority. The array is indexed by priority. */ + +TC_TCB *TCD_Priority_List[TC_PRIORITIES]; + + +/* TCD_Priority_Groups is a 32-bit unsigned integer that is used as a bit + map. Each bit corresponds to an 8-priority group. For example, if bit 0 + is set, at least one task of priority 0 through 8 is ready for execution. */ + +UNSIGNED TCD_Priority_Groups; + + +/* TCD_Sub_Priority_Groups is an array of sub-priority groups. These are + also used as bit maps. Index 0 of this array corresponds to priorities + 0 through 8. Bit 0 of this element represents priority 0, while bit 7 + represents priority 7. */ + +DATA_ELEMENT TCD_Sub_Priority_Groups[TC_MAX_GROUPS]; + + +/* TCD_Lowest_Set_Bit is nothing more than a standard lookup table. The + table is indexed by values ranging from 1 to 255. The value at that + position in the table indicates the number of the lowest set bit. This is + used to determine the highest priority task represented in the previously + defined bit maps. */ + +UNSIGNED_CHAR TCD_Lowest_Set_Bit[] = {0, + 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, + 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, + 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, + 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, + 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, + 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, + 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, + 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, + 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, + 0, 2, 0, 1, 0}; + + +/* TCD_Highest_Priority contains the highest priority task ready for execution. + Note that this does not necessarily represent the priority of the currently + executing task. This is true if the currently executing task has preemption + disabled. If no tasks are executing, this variable is set to the maximum + priority. */ + +INT TCD_Highest_Priority; + + +/* TCD_Execute_Task is a pointer to the task to execute. Note that this + pointer does not necessarily point to the currently executing task. There + are several points in the system where this is true. One situation is + when preemption is about to take place. Another situation can result from + a internal protection conflict. */ + +TC_TCB *TCD_Execute_Task; + + +/* TCD_Created_HISRs_List is the head pointer of the list of created High- + Level Interrupt Service Routines (HISR). If this pointer is NU_NULL, there + are no HISRs currently created. */ + +CS_NODE *TCD_Created_HISRs_List; + + +/* TCD_Total_HISRs contains the number of currently created HISRs. */ + +UNSIGNED TCD_Total_HISRs; + + +/* TCD_Active_HISR_Heads is an array of active HISR list head pointers. + There are three HISR priorities available. The HISR priority is an index + into this table. Priority/index 0 represents the highest priority. */ + +TC_HCB *TCD_Active_HISR_Heads[TC_HISR_PRIORITIES]; + + +/* TCD_Active_HISR_Tails is an array of active HISR list tail pointers. + There are three HISR priorities available. The HISR priority is an index + into this table. Priority/index 0 represents the highest priority. */ + +TC_HCB *TCD_Active_HISR_Tails[TC_HISR_PRIORITIES]; + + +/* TCD_Execute_HISR contains a pointer to the highest priority HISR to execute. + If this pointer is NU_NULL, no HISRs are currently activated. Note that + the current thread pointer is not always equal to this pointer. */ + +TC_HCB *TCD_Execute_HISR; + + +/* TCD_Current_Thread points to the control block of the currently executing + thread of execution. Therefore, this variable points at either a TC_TCB + or a TC_HCB structure. Except for initialization, this variable is set + and cleared in the target dependent portion of this component. */ + +VOID *TCD_Current_Thread; + + +/* TCD_System_Stack contains the system stack base pointer. When the system + is idle or in interrupt processing the system stack pointer is used. This + variable is usually setup during target dependent initialization. */ + +VOID *TCD_System_Stack; + + +/* TCD_Registered_LISRs is a list that specifies whether or not a + LISR is registered for a given interrupt vector. If the value in the + list indexed by the vector is non-zero, then that value can be used + as the index into the list of LISR pointers to find the actual registered + LISR. */ + +UNSIGNED_CHAR TCD_Registered_LISRs[NU_MAX_VECTORS+1]; + + +/* TCD_LISR_Pointers is a list of LISR pointers that indicate the LISR function + to call when the interrupt occurs. If the entry is NULL, it is + available. */ + +VOID (*TCD_LISR_Pointers[NU_MAX_LISRS+1])(INT vector); + + +/* TCD_Interrupt_Count contains the number of Interrupt Service Routines (ISRs) + currently in progress. If the contents of this variable is zero, then no + interrupts are in progress. If the contents are greater than 1, nested + interrupts are being processed. */ + +INT TCD_Interrupt_Count; + + +/* TCD_Stack_Switched contains a flag indicating that the system stack was + switched to after the thread's context was saved. This variable is not + used in all ports. */ + +INT TCD_Stack_Switched; + + +/* TCD_List_Protect is a structure that is used to protect against multiple + access to the list of established tasks. */ + +TC_PROTECT TCD_List_Protect; + + +/* TCD_System_Protect is a structure that is used to provide protection + against multiple threads accessing the same system structures at the + same time. */ + +TC_PROTECT TCD_System_Protect; + + +/* TCD_LISR_Protect is a structure that is used to provide protection against + multiple threads accessing the LISR registration structures at the same + time. */ + +TC_PROTECT TCD_LISR_Protect; + + +/* TCD_HISR_Protect is a structure that is used to provide protection against + multiple threads accessing the created HISR linked-list at the same time. */ + +TC_PROTECT TCD_HISR_Protect; + + +/* TCD_Interrupt_Level is a variable that contains the enabled interrupt + level. If the target processor does not have multiple enable interrupt + levels, this variable is a boolean. */ + +INT TCD_Interrupt_Level; + + +/* TCD_Unhandled_Interrupt is a variable that contains the last unhandled + interrupt in system error conditions. */ + +INT TCD_Unhandled_Interrupt; + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/tcf.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,672 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* tcf.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* TC - Thread Control */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains information (fact) routines for the Thread */ +/* Control component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* TCF_Established_Tasks Number of created tasks */ +/* TCF_Established_HISRs Number of created HISRs */ +/* TCF_Task_Pointers Build list of task pointers */ +/* TCF_HISR_Pointers Build list of HISR pointers */ +/* TCF_Task_Information Retrieve task information */ +/* TCF_HISR_Information Retrieve HISR information */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* in_extr.h Initialization/Interrupt */ +/* functions */ +/* tm_extr.h Timer Control function */ +/* er_extr.h Error handling function */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Created initial version 1.1 from */ +/* original 1.0g version of TCC.C */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 11-18-1996 Protected Informational service */ +/* from NULL Control Block pointers */ +/* creating 1.2a. (SPR220) */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "in_extr.h" /* Initialization/Interrupt */ + /* functions */ +#include "tm_extr.h" /* Timer control functions */ +#include "er_extr.h" /* Error handling function */ +#include "hi_extr.h" /* History functions */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *TCD_Created_Tasks_List; +extern UNSIGNED TCD_Total_Tasks; +extern TC_TCB *TCD_Priority_List[TC_PRIORITIES]; +extern UNSIGNED TCD_Priority_Groups; +extern DATA_ELEMENT TCD_Sub_Priority_Groups[TC_MAX_GROUPS]; +extern UNSIGNED_CHAR TCD_Lowest_Set_Bit[]; +extern INT TCD_Highest_Priority; +extern TC_TCB *TCD_Execute_Task; +extern VOID *TCD_Current_Thread; +extern UNSIGNED_CHAR TCD_Registered_LISRs[NU_MAX_VECTORS+1]; +extern VOID (*TCD_LISR_Pointers[NU_MAX_LISRS+1])(INT vector); +extern INT TCD_Interrupt_Count; +extern INT TCD_Stack_Switched; +extern TC_PROTECT TCD_List_Protect; +extern TC_PROTECT TCD_Schedule_Protect; +extern TC_PROTECT TCD_LISR_Protect; +extern CS_NODE *TCD_Created_HISRs_List; +extern UNSIGNED TCD_Total_HISRs; +extern TC_PROTECT TCD_HISR_Protect; +extern INT TCD_Unhandled_Interrupt; + + +/* Define external inner-component function calls that are not available to + other components. */ + +VOID TCT_Build_Task_Stack(TC_TCB *task_ptr); +VOID TCT_Build_HISR_Stack(TC_HCB *hisr_ptr); +VOID TCT_Build_Signal_Frame(TC_TCB *task_ptr); +VOID TCT_Protect_Switch(TC_TCB *task); +VOID TCT_Signal_Exit(VOID); + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCF_Established_Tasks */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the current number of established tasks. */ +/* Tasks previously deleted are no longer considered established. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* TCD_Total_Tasks Number of established tasks */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +UNSIGNED TCF_Established_Tasks(VOID) +{ + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Return the number of established tasks. */ + return(TCD_Total_Tasks); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCF_Established_HISRs */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the current number of established HISRs. */ +/* HISRs previously deleted are no longer considered established. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* TCD_Total_HISRs Number of established HISRs */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +UNSIGNED TCF_Established_HISRs(VOID) +{ + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Return the number of established HISRs. */ + return(TCD_Total_HISRs); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCF_Task_Pointers */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function builds a list of task pointers, starting at the */ +/* specified location. The number of task pointers placed in the */ +/* list is equivalent to the total number of tasks or the maximum */ +/* number of pointers specified in the call. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_System_Protect Protect task created list */ +/* TCT_Unprotect Release protection of list */ +/* */ +/* INPUTS */ +/* */ +/* pointer_list Pointer to the list area */ +/* maximum_pointers Maximum number of pointers */ +/* */ +/* OUTPUTS */ +/* */ +/* pointers Number of tasks placed in */ +/* list */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected pointer retrieval */ +/* loop, resulting in version 1.0c */ +/* 08-09-1993 Verified version 1.0c */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED TCF_Task_Pointers(NU_TASK **pointer_list, UNSIGNED maximum_pointers) +{ + +CS_NODE *node_ptr; /* Pointer to each TCB */ +UNSIGNED pointers; /* Number of pointers in list*/ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Initialize the number of pointers returned. */ + pointers = 0; + + /* Protect the task created list. */ + TCT_Protect(&TCD_List_Protect); + + /* Loop until all task pointers are in the list or until the maximum + list size is reached. */ + node_ptr = TCD_Created_Tasks_List; + while ((node_ptr) && (pointers < maximum_pointers)) + { + + /* Place the node into the destination list. */ + *pointer_list++ = (NU_TASK *) node_ptr; + + /* Increment the pointers variable. */ + pointers++; + + /* Position the node pointer to the next node. */ + node_ptr = node_ptr -> cs_next; + + /* Determine if the pointer is at the head of the list. */ + if (node_ptr == TCD_Created_Tasks_List) + + /* The list search is complete. */ + node_ptr = NU_NULL; + } + + /* Release protection. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the number of pointers in the list. */ + return(pointers); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCF_HISR_Pointers */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function builds a list of HISR pointers, starting at the */ +/* specified location. The number of HISR pointers placed in the */ +/* list is equivalent to the total number of HISRs or the maximum */ +/* number of pointers specified in the call. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect HISR created list */ +/* TCT_Unprotect Release protection of list */ +/* */ +/* INPUTS */ +/* */ +/* pointer_list Pointer to the list area */ +/* maximum_pointers Maximum number of pointers */ +/* */ +/* OUTPUTS */ +/* */ +/* Number of HISRs placed in */ +/* list */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected pointer retrieval */ +/* loop, resulting in version 1.0c */ +/* 08-09-1993 Verified version 1.0c */ +/* 03-01-1994 Modified function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED TCF_HISR_Pointers(NU_HISR **pointer_list, UNSIGNED maximum_pointers) +{ + +CS_NODE *node_ptr; /* Pointer to each TCB */ +UNSIGNED pointers; /* Number of pointers in list*/ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Initialize the number of pointers returned. */ + pointers = 0; + + /* Protect the HISR created list. */ + TCT_Protect(&TCD_HISR_Protect); + + /* Loop until all HISR pointers are in the list or until the maximum + list size is reached. */ + node_ptr = TCD_Created_HISRs_List; + while ((node_ptr) && (pointers < maximum_pointers)) + { + + /* Place the node into the destination list. */ + *pointer_list++ = (NU_HISR *) node_ptr; + + /* Increment the pointers variable. */ + pointers++; + + /* Position the node pointer to the next node. */ + node_ptr = node_ptr -> cs_next; + + /* Determine if the pointer is at the head of the list. */ + if (node_ptr == TCD_Created_HISRs_List) + + /* The list search is complete. */ + node_ptr = NU_NULL; + } + + /* Release protection. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the number of pointers in the list. */ + return(pointers); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCF_Task_Information */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns information about the specified task. */ +/* However, if the supplied task pointer is invalid, the function */ +/* simply returns an error status. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_System_Protect Protect scheduling info */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Pointer to the task */ +/* name Destination for the name */ +/* status Destination for task status */ +/* scheduled_count Destination for scheduled */ +/* count of the task */ +/* priority Destination for task priority*/ +/* preempt Destination for preempt flag */ +/* time_slice Destination for time slice */ +/* stack_base Destination for pointer to */ +/* base of task's stack */ +/* stack_size Destination for stack size */ +/* minimum_stack Destination for the minimum */ +/* running size of the stack */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If a valid task pointer is */ +/* supplied */ +/* NU_INVALID_TASK If task pointer is invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* changed protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 11-18-1996 Corrected SPR220. */ +/* */ +/*************************************************************************/ +STATUS TCF_Task_Information(NU_TASK *task_ptr, CHAR *name, + DATA_ELEMENT *status, UNSIGNED *scheduled_count, + DATA_ELEMENT *priority, OPTION *preempt, UNSIGNED *time_slice, + VOID **stack_base, UNSIGNED *stack_size, UNSIGNED *minimum_stack) +{ + +R1 TC_TCB *task; /* Task control block ptr */ +INT i; /* Working index */ +STATUS completion; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move task control block pointer into internal pointer. */ + task = (TC_TCB *) task_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Determine if this task is valid. */ + if ((task != NU_NULL) && (task -> tc_id == TC_TASK_ID)) + { + + /* Protect against scheduling changes. */ + TCT_System_Protect(); + + /* The task pointer is successful. Reflect this in the completion + status and fill in the actual information. */ + completion = NU_SUCCESS; + + /* Copy the task's name. */ + for (i = 0; i < NU_MAX_NAME; i++) + *name++ = task -> tc_name[i]; + + /* Determine the preemption posture. */ + if (task -> tc_preemption) + *preempt = NU_PREEMPT; + else + *preempt = NU_NO_PREEMPT; + + /* Setup the remaining fields. */ + *status = task -> tc_status; + *scheduled_count = task -> tc_scheduled; + *priority = task -> tc_priority; + *time_slice = task -> tc_time_slice; + *stack_base = task -> tc_stack_start; + *stack_size = task -> tc_stack_size; + *minimum_stack = task -> tc_stack_minimum; + + /* Release protection. */ + TCT_Unprotect(); + } + else + + /* Indicate that the task pointer is invalid. */ + completion = NU_INVALID_TASK; + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the appropriate completion status. */ + return(completion); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCF_HISR_Information */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns information about the specified HISR. */ +/* However, if the supplied HISR pointer is invalid, the function */ +/* simply returns an error status. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_System_Protect Protect scheduling info */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* hisr_ptr Pointer to the hisr */ +/* name Destination for the name */ +/* scheduled_count Destination for scheduled */ +/* count of the HISR */ +/* priority Destination for HISR priority*/ +/* stack_base Destination for pointer to */ +/* base of HISR's stack */ +/* stack_size Destination for stack size */ +/* minimum_stack Destination for the minimum */ +/* running size of the stack */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If a valid HISR pointer is */ +/* supplied */ +/* NU_INVALID_HISR If HISR pointer is invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* changed protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 11-18-1996 Corrected SPR220. */ +/* */ +/*************************************************************************/ +STATUS TCF_HISR_Information(NU_HISR *hisr_ptr, CHAR *name, + UNSIGNED *scheduled_count, DATA_ELEMENT *priority, + VOID **stack_base, UNSIGNED *stack_size, UNSIGNED *minimum_stack) +{ + +R1 TC_HCB *hisr; /* HISR control block ptr */ +INT i; /* Working index */ +STATUS completion; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input HISR control block pointer into internal pointer. */ + hisr = (TC_HCB *) hisr_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Determine if this HISR is valid. */ + if ((hisr != NU_NULL) && (hisr -> tc_id == TC_HISR_ID)) + { + + /* Protect against scheduling changes. */ + TCT_System_Protect(); + + /* The HISR pointer is successful. Reflect this in the completion + status and fill in the actual information. */ + completion = NU_SUCCESS; + + /* Copy the hisr's name. */ + for (i = 0; i < NU_MAX_NAME; i++) + *name++ = hisr -> tc_name[i]; + + /* Setup the remaining fields. */ + *scheduled_count = hisr -> tc_scheduled; + *priority = hisr -> tc_priority; + *stack_base = hisr -> tc_stack_start; + *stack_size = hisr -> tc_stack_size; + *minimum_stack = hisr -> tc_stack_minimum; + + /* Release protection. */ + TCT_Unprotect(); + } + else + + /* Indicate that the HISR pointer is invalid. */ + completion = NU_INVALID_HISR; + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the appropriate completion status. */ + return(completion); +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/tcfe.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,155 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* tcfe.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* TC - Thread Control */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains routines that check parameters to the */ +/* routines that return information about a thread. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* TCFE_Task_Information Retrieve task information */ +/* */ +/* DEPENDENCIES */ +/* */ +/* tc_extr.h Thread Control functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 11-07-2002 Released version 1.14 */ +/* */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "tc_extr.h" /* Thread control functions */ + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCFE_Task_Information */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the function that returns information about a task. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_System_Protect Protect scheduling info */ +/* TCT_Unprotect Release protection */ +/* TCF_Task_Information Returns task information */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Pointer to the task */ +/* name Destination for the name */ +/* status Destination for task status */ +/* scheduled_count Destination for scheduled */ +/* count of the task */ +/* priority Destination for task priority*/ +/* preempt Destination for preempt flag */ +/* time_slice Destination for time slice */ +/* stack_base Destination for pointer to */ +/* base of task's stack */ +/* stack_size Destination for stack size */ +/* minimum_stack Destination for the minimum */ +/* running size of the stack */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If a valid task pointer is */ +/* supplied */ +/* NU_INVALID_TASK If task pointer is invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* */ +/*************************************************************************/ +STATUS TCFE_Task_Information(NU_TASK *task_ptr, CHAR *name, + DATA_ELEMENT *status, UNSIGNED *scheduled_count, + DATA_ELEMENT *priority, OPTION *preempt, UNSIGNED *time_slice, + VOID **stack_base, UNSIGNED *stack_size, UNSIGNED *minimum_stack) +{ + +STATUS completion; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Check if parameters are valid. task is tested in TCF_Task_Inforation */ + if (name == NU_NULL) + completion = NU_INVALID_POINTER; + else if (preempt == NU_NULL) + completion = NU_INVALID_POINTER; + else if (status == NU_NULL) + completion = NU_INVALID_POINTER; + else if (scheduled_count == NU_NULL) + completion = NU_INVALID_POINTER; + else if (priority == NU_NULL) + completion = NU_INVALID_POINTER; + else if (time_slice == NU_NULL) + completion = NU_INVALID_POINTER; + else if (stack_base == NU_NULL) + completion = NU_INVALID_POINTER; + else if (stack_size == NU_NULL) + completion = NU_INVALID_POINTER; + else if (minimum_stack == NU_NULL) + completion = NU_INVALID_POINTER; + else + completion = TCF_Task_Information(task_ptr, name, status, scheduled_count, + priority, preempt, time_slice, stack_base, + stack_size, minimum_stack); + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + return(completion); +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/tci.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,234 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* tci.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* TC - Thread Control */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the initialization routine for this */ +/* component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* TCI_Initialize Thread Control Initialization*/ +/* */ +/* DEPENDENCIES */ +/* */ +/* tc_defs.h Thread Control constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected problem initializing */ +/* the LISR association table, */ +/* resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Changed to initialize the system */ +/* protection rather than the */ +/* schedule protection, resulting */ +/* in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_defs.h" /* Common Service constants */ +#include "tc_defs.h" /* Thread Control constants */ +#include "tc_extr.h" /* Thread Control interfaces */ + +/* Define external inner-component global data references. */ + +extern CS_NODE *TCD_Created_Tasks_List; +extern UNSIGNED TCD_Total_Tasks; +extern TC_TCB *TCD_Priority_List[TC_PRIORITIES]; +extern UNSIGNED TCD_Priority_Groups; +extern DATA_ELEMENT TCD_Sub_Priority_Groups[TC_MAX_GROUPS]; +extern INT TCD_Highest_Priority; +extern TC_TCB *TCD_Execute_Task; +extern VOID *TCD_Current_Thread; +extern UNSIGNED_CHAR TCD_Registered_LISRs[NU_MAX_VECTORS+1]; +extern VOID (*TCD_LISR_Pointers[NU_MAX_LISRS+1])(INT vector); +extern INT TCD_Interrupt_Count; +extern INT TCD_Stack_Switched; +extern TC_PROTECT TCD_List_Protect; +extern TC_PROTECT TCD_System_Protect; +extern TC_PROTECT TCD_LISR_Protect; +extern CS_NODE *TCD_Created_HISRs_List; +extern UNSIGNED TCD_Total_HISRs; +extern TC_HCB *TCD_Active_HISR_Heads[TC_HISR_PRIORITIES]; +extern TC_HCB *TCD_Active_HISR_Tails[TC_HISR_PRIORITIES]; +extern TC_HCB *TCD_Execute_HISR; +extern TC_PROTECT TCD_HISR_Protect; +extern INT TCD_Interrupt_Level; + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCI_Initialize */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function initializes the data structures that control the */ +/* operation of the TC component. The system is initialized as */ +/* idle. This routine must be executed from Supervisor mode in */ +/* Supervisor/User mode switching kernels. */ +/* */ +/* CALLED BY */ +/* */ +/* INC_Initialize System initialization */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* TCD_Created_Tasks_List List of created tasks */ +/* TCD_Total_Tasks Number of created tasks */ +/* TCD_Priority_List Ready task array */ +/* TCD_Priority_Groups Ready priority group bit map */ +/* TCD_Sub_Priority_Groups Sub-priority groups bit map */ +/* TCD_Highest_Priority Highest priority task */ +/* TCD_Execute_Task Top priority task to execute */ +/* TCD_Created_HISRs_List List of created HISRs */ +/* TCD_Total_HISRs Number of created HISRs */ +/* TCD_Active_HISR_Heads Active HISR list head ptrs */ +/* TCD_Active_HISR_Tails Active HISR list tail ptrs */ +/* TCD_Execute_HISR Top priority HISR to execute */ +/* TCD_Current_Thread Current thread pointer */ +/* TCD_Registered_LISRs Registered LISRs list */ +/* TCD_LISR_Pointers Pointers to active LISRs */ +/* TCD_Interrupt_Count Interrupt in progress counter*/ +/* TCD_Stack_Switched Interrupt stack switched flag*/ +/* TCD_List_Protect Protection of task list */ +/* TCD_Schedule_Protect Protection of scheduling */ +/* data structures. */ +/* TCD_HISR_Protect Protection of created HISR */ +/* list */ +/* TCD_Interrupt_Level Enable interrupt level */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected problem initializing */ +/* the LISR association table, */ +/* resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Changed to initialize the system */ +/* protection rather than the */ +/* schedule protection, resulting */ +/* in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +VOID TCI_Initialize(VOID) +{ + +int i; /* Working index variable */ + + + /* Initialize the created task list to NU_NULL. */ + TCD_Created_Tasks_List = NU_NULL; + + /* Initialize the total number of created tasks to 0. */ + TCD_Total_Tasks = 0; + + /* Initialize the array of ready task lists. */ + for (i = 0; i < TC_PRIORITIES; i++) + TCD_Priority_List[i] = 0; + + /* Initialize the bit maps that represent that at least one task is + ready at the same priority level. */ + TCD_Priority_Groups = 0; + + for (i = 0; i < TC_MAX_GROUPS; i++) + TCD_Sub_Priority_Groups[i] = 0; + + /* Initialize the highest priority flag. */ + TCD_Highest_Priority = TC_PRIORITIES; + + /* Initialize pointers to the task to execute, HISR to execute, + and current thread of execution. */ + TCD_Execute_Task = NU_NULL; + TCD_Execute_HISR = NU_NULL; + TCD_Current_Thread = NU_NULL; + + /* Initialize the created HISRs list to NU_NULL. */ + TCD_Created_HISRs_List = NU_NULL; + + /* Initialize the total number of created HISRs to 0. */ + TCD_Total_HISRs = 0; + + /* Initialize the array of ready HISR list pointers. */ + for (i = 0; i < TC_HISR_PRIORITIES; i++) + { + TCD_Active_HISR_Heads[i] = NU_NULL; + TCD_Active_HISR_Tails[i] = NU_NULL; + } + + /* Initialize the LISR interrupt control data structures. */ + for (i = 0; i <= NU_MAX_VECTORS; i++) + TCD_Registered_LISRs[i] = NU_FALSE; + + for (i = 0; i <= NU_MAX_LISRS; i++) + TCD_LISR_Pointers[i] = NU_NULL; + + /* Initialize the interrupt processing variables. */ + TCD_Interrupt_Count = 0; + TCD_Stack_Switched = 0; + + /* Initialize the task control protection structures. */ + TCD_List_Protect.tc_tcb_pointer = NU_NULL; + TCD_System_Protect.tc_tcb_pointer = NU_NULL; + TCD_LISR_Protect.tc_tcb_pointer = NU_NULL; + TCD_HISR_Protect.tc_tcb_pointer = NU_NULL; + + /* Initialize the interrupt level to enable all interrupts. */ + TCD_Interrupt_Level = NU_ENABLE_INTERRUPTS; +} + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/tcs.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,1154 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* tcs.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* TC - Thread Control */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains supplemental routines for the Thread Control */ +/* component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* TCS_Change_Priority Change task's priority */ +/* TCS_Change_Preemption Change task's preemption */ +/* TCS_Change_Time_Slice Change task's time-slice */ +/* TCS_Control_Signals Control signals */ +/* TCS_Receive_Signals Receive signals */ +/* TCS_Register_Signal_Handler Register signal handler */ +/* TCS_Send_Signals Send signals to a task */ +/* */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* in_extr.h Initialization/Interrupt */ +/* functions */ +/* tm_extr.h Timer Control function */ +/* er_extr.h Error handling function */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Created initial version 1.1 from */ +/* previous version of TCC.C */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-04-1996 Modified TCS_Send_Signals, */ +/* resulting in version 1.1+ */ +/* (spr 107) */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "in_extr.h" /* Initialization/Interrupt */ + /* functions */ +#include "tm_extr.h" /* Timer control functions */ +#include "er_extr.h" /* Error handling function */ +#include "hi_extr.h" /* History functions */ +#include "profiler.h" /* ProView interface */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *TCD_Created_Tasks_List; +extern TC_TCB *TCD_Priority_List[TC_PRIORITIES]; +extern UNSIGNED TCD_Priority_Groups; +extern DATA_ELEMENT TCD_Sub_Priority_Groups[TC_MAX_GROUPS]; +extern UNSIGNED_CHAR TCD_Lowest_Set_Bit[]; +extern INT TCD_Highest_Priority; +extern TC_TCB *TCD_Execute_Task; +extern VOID *TCD_Current_Thread; +extern TC_PROTECT TCD_System_Protect; +extern INT TMD_Time_Slice_State; + + + +/* Define external inner-component function calls that are not available to + other components. */ + +VOID TCT_Build_Signal_Frame(TC_TCB *task_ptr); +VOID TCT_Protect_Switch(TC_TCB *task); +VOID TCT_Signal_Exit(VOID); + + +/* Define internal function calls. */ + +VOID TCC_Signal_Shell(VOID); + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCS_Change_Priority */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function changes the priority of the specified task. The */ +/* priority of a suspended or a ready task can be changed. If the */ +/* new priority necessitates a context switch, control is */ +/* transferred back to the system. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* TCSE_Change_Priority Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Protect Protect scheduling data */ +/* TCT_Set_Execute_Task Set TCD_Execute_Task pointer */ +/* TCT_Unprotect Release protection of data */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Task control block pointer */ +/* new_priority New priority for task */ +/* */ +/* OUTPUTS */ +/* */ +/* old_priority Original task priority */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* modified protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/* 10-4-1999 Bug fixes - return if new */ +/* priority equals old priority */ +/* and don't move the head pointer */ +/* unless the head node is changing */ +/*************************************************************************/ +OPTION TCS_Change_Priority(NU_TASK *task_ptr, OPTION new_priority) +{ + +R1 TC_TCB *task; /* Task control block ptr */ +R2 TC_TCB *head; /* Head list pointer */ +R3 INT index; /* Working index variable */ +OPTION old_priority; /* Previous priority of task */ +DATA_ELEMENT temp; /* Temporary variable */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move task control block pointer into internal pointer. */ + task = (TC_TCB *) task_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_CHANGE_PRIORITY_ID, (UNSIGNED) task, + (UNSIGNED) new_priority, (UNSIGNED) 0); + +#endif + + /* Protect against multiple access to the scheduling list. */ + TCT_Protect(&TCD_System_Protect); + + /* Save the old priority of the task. */ + old_priority = task -> tc_priority; + + + /* BUG FIX this should probably go into an error checking routine instead of here */ + if (!(task -> tc_priority == new_priority)) + { + + + /* Check to see if the task is currently ready. */ + if (task -> tc_status == NU_READY) + { + + /* Remove the task from the ready list. */ + + /* Determine if the task is the only one on the list. */ + if (task -> tc_ready_next == task) + { + + /* Only task on the list. Clear the task's pointers and + clear the entry in the priority table. */ + task -> tc_ready_next = NU_NULL; + task -> tc_ready_previous = NU_NULL; + *(task -> tc_priority_head) = NU_NULL; + + /* Clear the sub-priority group. */ + *(task -> tc_sub_priority_ptr) = + *(task -> tc_sub_priority_ptr) & ~(task -> tc_sub_priority); + + /* Determine if the main priority group needs to be cleared. + This is only true if there are no other bits set in this + sub-priority. */ + if (*(task -> tc_sub_priority_ptr) == 0) + + /* Clear the main priority group bit. */ + TCD_Priority_Groups = + TCD_Priority_Groups & ~(task -> tc_priority_group); + } + else + { + + /* Not the only task ready at the same priority level. */ + + /* Remove from the linked-list. */ + (task -> tc_ready_previous) -> tc_ready_next = + task -> tc_ready_next; + (task -> tc_ready_next) -> tc_ready_previous = + task -> tc_ready_previous; + + + + /* Update the head pointer. */ + /* BUG FIX - update head if head is changing priority - leave + it alone otherwise! */ + if(*(task -> tc_priority_head) == task ) + *(task -> tc_priority_head) = task -> tc_ready_next; + + /* Clear the next and previous pointers. */ + task -> tc_ready_next = NU_NULL; + task -> tc_ready_previous = NU_NULL; + } + + /* Now add in the task at the new priority. */ + task -> tc_priority = new_priority; + + /* Build the other priority information. */ + task -> tc_priority = new_priority; + task -> tc_priority_head = &(TCD_Priority_List[new_priority]); + task -> tc_sub_priority = (DATA_ELEMENT) (1 << (new_priority & 7)); + task -> tc_priority_group = ((UNSIGNED) 1) << (new_priority >> 3); + task -> tc_sub_priority_ptr = + &(TCD_Sub_Priority_Groups[(new_priority >> 3)]); + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTask(task,RT_PROF_CHANGE_PRIORITY); +#endif + /* Link the task into the new priority list. */ + head = *(task -> tc_priority_head); + + /* Determine if the list is non-empty. */ + if (head) + { + + /* Add the TCB to the end of the ready list. */ + task -> tc_ready_previous = head -> tc_ready_previous; + (task -> tc_ready_previous) -> tc_ready_next = task; + task -> tc_ready_next = head; + (task -> tc_ready_next) -> tc_ready_previous = task; + + /* Note that the priority bit map does not need to be + modified since there are other active tasks at the + same priority. */ + } + else + { + + /* Add the TCB to an empty list. */ + task -> tc_ready_previous = task; + task -> tc_ready_next = task; + *(task -> tc_priority_head)= task; + + /* Update the priority group bit map to indicate that this + priority now has a task ready. */ + TCD_Priority_Groups = + TCD_Priority_Groups | (task -> tc_priority_group); + + /* Update the sub-priority bit map to show that this priority + is ready. */ + *(task -> tc_sub_priority_ptr) = + (*(task -> tc_sub_priority_ptr)) | task -> tc_sub_priority; + } + + /* Determine the highest priority task in the system. */ + if (TCD_Priority_Groups & TC_HIGHEST_MASK) + + /* Base of sub-group is 0. */ + index = 0; + + else if (TCD_Priority_Groups & TC_NEXT_HIGHEST_MASK) + + /* Base of sub-group is 8. */ + index = 8; + + else if (TCD_Priority_Groups & TC_NEXT_LOWEST_MASK) + + /* Base of sub-group is 16. */ + index = 16; + else + + /* Base of sub-group is 24. */ + index = 24; + + /* Calculate the highest available priority. */ + index = index + TCD_Lowest_Set_Bit[(INT) + ((TCD_Priority_Groups >> index) & TC_HIGHEST_MASK)]; + + /* Get the mask of the priority within the group of 8 priorities. */ + temp = TCD_Sub_Priority_Groups[index]; + + /* Calculate the actual priority. */ + TCD_Highest_Priority = (index << 3) + TCD_Lowest_Set_Bit[temp]; + + /* Check for preemption. */ + if ((TCD_Highest_Priority <= ((INT) TCD_Execute_Task -> tc_priority)) + && (TCD_Execute_Task -> tc_preemption)) + { + + /* Update the current task pointer. */ + TCT_Set_Execute_Task(TCD_Priority_List[TCD_Highest_Priority]); + + /* Now, check and see if the current thread is a task. + If so, return a status that indicates a context + switch is needed. */ + if ((TCD_Current_Thread) && + (((TC_TCB *) TCD_Current_Thread) -> tc_id == TC_TASK_ID)) + + /* Transfer control to the system. */ + TCT_Control_To_System(); + } + } + else + { + + /* Just modify the priority. */ + task -> tc_priority = new_priority; + + /* Build the other priority information. */ + task -> tc_priority = new_priority; + task -> tc_priority_head = &(TCD_Priority_List[new_priority]); + task -> tc_sub_priority = (DATA_ELEMENT) (1 << (new_priority & 7)); + task -> tc_priority_group = ((UNSIGNED) 1) << (new_priority >> 3); + task -> tc_sub_priority_ptr = + &(TCD_Sub_Priority_Groups[(new_priority >> 3)]); + } +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTask(task,RT_PROF_CHANGE_PRIORITY); +#endif + } + + /* Release the protection of the scheduling list. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the old priority. */ + return(old_priority); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCS_Change_Preemption */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function changes the preemption posture of the calling */ +/* task. Preemption for a task may be enabled or disabled. If */ +/* it is disabled, the task runs until it suspends or relinquishes. */ +/* If a preemption is pending, a call to this function to enable */ +/* preemption causes a context switch. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* TCSE_Change_Preemption Error checking function */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Transfer control to system */ +/* TCT_Protect Protect scheduling info */ +/* TCT_Set_Execute_Task Set TCD_Execute_Task pointer */ +/* TCT_Unprotect Release protection of info */ +/* */ +/* INPUTS */ +/* */ +/* preempt Preempt selection parameter */ +/* */ +/* OUTPUTS */ +/* */ +/* old_preempt Original preempt value */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +OPTION TCS_Change_Preemption(OPTION preempt) +{ + +TC_TCB *task; /* Pointer to task */ +OPTION old_preempt; +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_CHANGE_PREEMPTION_ID, (UNSIGNED) preempt, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Protect the scheduling information. */ + TCT_Protect(&TCD_System_Protect); + + /* Pickup the current thread and place it in the task pointer. */ + task = (TC_TCB *) TCD_Current_Thread; + + /* Save the old preempt value. */ + if (task -> tc_preemption) + + /* Previously enabled. */ + old_preempt = NU_PREEMPT; + else + + /* Previously disabled. */ + old_preempt = NU_NO_PREEMPT; + + /* Process the new value. */ + if (preempt == NU_NO_PREEMPT) + + /* Disable preemption. */ + TCD_Execute_Task -> tc_preemption = NU_FALSE; + else + { + + /* Enable preemption. */ + task -> tc_preemption = NU_TRUE; + + /* Check for a preemption condition. */ + if ((task == TCD_Execute_Task) && + (TCD_Highest_Priority < ((INT) TCD_Execute_Task -> tc_priority))) + { + + /* Preempt the current task. */ + TCT_Set_Execute_Task(TCD_Priority_List[TCD_Highest_Priority]); + + /* Transfer control to the system. */ + TCT_Control_To_System(); + } + } + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTask(task,RT_PROF_CHANGE_PREEMPTION); +#endif + + /* Release protection of information. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the previous preemption posture. */ + return(old_preempt); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCS_Change_Time_Slice */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function changes the time slice of the specified task. A */ +/* time slice value of 0 disables time slicing. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* TCES_Change_Preemption Error checking function */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect scheduling info */ +/* TCT_Unprotect Release protection of info */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Task control block pointer */ +/* time_slice New time slice value */ +/* */ +/* OUTPUTS */ +/* */ +/* old_time_slice Original time slice value */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* modified protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED TCS_Change_Time_Slice(NU_TASK *task_ptr, UNSIGNED time_slice) +{ + +TC_TCB *task; /* Task control block ptr */ +UNSIGNED old_time_slice; /* Old time slice value */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input task control block pointer into internal pointer. */ + task = (TC_TCB *) task_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_CHANGE_TIME_SLICE_ID, (UNSIGNED) task, + (UNSIGNED) time_slice, (UNSIGNED) 0); + +#endif + + /* Protect the scheduling information. */ + TCT_Protect(&TCD_System_Protect); + + /* Save the old time slice value. */ + old_time_slice = task -> tc_time_slice; + + /* Store the new time slice value. */ + task -> tc_time_slice = time_slice; + task -> tc_cur_time_slice = time_slice; + + /* Bug fix. Let the system know we have started a new time slice */ + TMD_Time_Slice_State = TM_ACTIVE; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTask(task,RT_PROF_CHANGE_TIME_SLICE); +#endif + /* Release protection of information. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the previous time slice value. */ + return(old_time_slice); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCS_Control_Signals */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function enables the specified signals and returns the */ +/* previous enable signal value back to the caller. If a newly */ +/* enabled signal is present and a signal handler is registered, */ +/* signal handling is started. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* TCSE_Control_Signals Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Signal_Shell Task signal execution */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect against other access */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* enable_signal_mask Enable signal mask */ +/* */ +/* OUTPUTS */ +/* */ +/* Previous signal enable mask */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 05-15-1993 Corrected problem with a comment */ +/* 05-15-1993 Verified comment repair */ +/* 03-01-1994 Added register optimizations, */ +/* modified protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED TCS_Control_Signals(UNSIGNED enable_signal_mask) +{ + +R1 TC_TCB *task; /* Task pointer */ +UNSIGNED old_enable_mask; /* Old enable signal mask */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_CONTROL_SIGNALS_ID,(UNSIGNED) enable_signal_mask, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Pickup the task pointer. */ + task = (TC_TCB *) TCD_Current_Thread; + + /* Protect against simultaneous access. */ + TCT_Protect(&TCD_System_Protect); + + /* Pickup the old signal mask. */ + old_enable_mask = task -> tc_enabled_signals; + + /* Put the new mask in. */ + task -> tc_enabled_signals = enable_signal_mask; + + /* Now, determine if the signal handler needs to be invoked. */ + if ((enable_signal_mask & task -> tc_signals) && + (!task -> tc_signal_active) && + (task -> tc_signal_handler)) + { + + /* Signal processing is required. */ + + /* Indicate that signal processing is in progress. */ + task -> tc_signal_active = NU_TRUE; + + /* Clear the saved stack pointer to indicate that this is an + in line signal handler call. */ + task -> tc_saved_stack_ptr = NU_NULL; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTask(task,RT_PROF_CONTROL_SIGNALS); +#endif + + /* Release protection from multiple access. */ + TCT_Unprotect(); + + /* Call the signal handling shell. */ + TCC_Signal_Shell(); + } + else + { + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTask(task,RT_PROF_CONTROL_SIGNALS); +#endif + + /* Release protection. */ + TCT_Unprotect(); + } + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the old enable mask. */ + return(old_enable_mask); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCS_Receive_Signals */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the current signals back to the caller. */ +/* Note that the signals are cleared automatically. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* TCSE_Receive_Signals Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect against other access */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* Current signals */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED TCS_Receive_Signals(VOID) +{ + +TC_TCB *task; /* Task pointer */ +UNSIGNED signals; /* Current signals */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_RECEIVE_SIGNALS_ID, (UNSIGNED) 0, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Pickup the task pointer. */ + task = (TC_TCB *) TCD_Current_Thread; + + /* Protect against simultaneous access. */ + TCT_Protect(&TCD_System_Protect); + + /* Pickup the current events. */ + signals = task -> tc_signals; + + /* Clear the current signals. */ + task -> tc_signals = 0; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTask(task,RT_PROF_RECEIVE_SIGNALS); +#endif + + /* Release protection. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the signals to the caller. */ + return(signals); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCS_Register_Signal_Handler */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function registers a signal handler for the calling task. */ +/* Note that if an enabled signal is present and this is the first */ +/* registered signal handler call, the signal is processed */ +/* immediately. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* TCSE_Register_Signal_Handler Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Signal_Shell Signal execution shell */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect against other access */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* signal_handler Signal execution shell */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 05-15-1993 Corrected problem with a comment */ +/* 05-15-1993 Verified comment repair */ +/* 03-01-1994 Added register optimizations, */ +/* modified protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TCS_Register_Signal_Handler(VOID (*signal_handler)(UNSIGNED)) +{ + +R1 TC_TCB *task; /* Task pointer */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_REGISTER_SIGNAL_HANDLER_ID, + (UNSIGNED) signal_handler, (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Pickup the task pointer. */ + task = (TC_TCB *) TCD_Current_Thread; + + /* Protect against simultaneous access. */ + TCT_Protect(&TCD_System_Protect); + + /* Put the new signal handler in. */ + task -> tc_signal_handler = signal_handler; + + /* Now, determine if the signal handler needs to be invoked. */ + if ((task -> tc_enabled_signals & task -> tc_signals) && + (!task -> tc_signal_active) && + (task -> tc_signal_handler)) + { + + /* Signal processing is required. */ + + /* Indicate that signal processing is in progress. */ + task -> tc_signal_active = NU_TRUE; + + /* Clear the saved stack pointer to indicate that this is an + in line signal handler call. */ + task -> tc_saved_stack_ptr = NU_NULL; + + /* Release protection from multiple access. */ + TCT_Unprotect(); + + /* Call the signal handling shell. */ + TCC_Signal_Shell(); + } + else + + /* Release protection. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return success. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCS_Send_Signals */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function sends the specified task the specified signals. */ +/* If enabled, the specified task is setup in order to process the */ +/* signals. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* TCSE_Send_Signals Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* TCC_Resume_Task Resume task that is suspended*/ +/* TCC_Signal_Shell Signal execution shell */ +/* TCT_Build_Signal_Frame Build a signal frame */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Control_To_System Control to system */ +/* TCT_Protect Protect against other access */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Task pointer */ +/* signals Signals to send to the task */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified function interface, */ +/* added register optimizations, */ +/* modified protection logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-04-1996 On line 995, changed tc_signals */ +/* to tc_enabled_signals, */ +/* resulting in version 1.1+ */ +/* (spr 107) */ +/* */ +/*************************************************************************/ +STATUS TCS_Send_Signals(NU_TASK *task_ptr, UNSIGNED signals) +{ + +R1 TC_TCB *task; /* Task control block ptr */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input task control block pointer into internal pointer. */ + task = (TC_TCB *) task_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_SEND_SIGNALS_ID, (UNSIGNED) signals, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Protect against simultaneous access. */ + TCT_Protect(&TCD_System_Protect); + + /* Or the new signals into the current signals. */ + task -> tc_signals = task -> tc_signals | signals; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTask(task,RT_PROF_SEND_SIGNALS); +#endif + /* Now, determine if the signal handler needs to be invoked. */ + if ((task -> tc_signals & task -> tc_enabled_signals) && + (!task -> tc_signal_active) && + (task -> tc_status != NU_TERMINATED) && + (task -> tc_status != NU_FINISHED) && + (task -> tc_signal_handler)) + { + + /* Indicate that signal processing is in progress. */ + task -> tc_signal_active = NU_TRUE; + + /* Signal processing is required. Determine if the task is sending + signals to itself or if the calling thread is not the current + task. */ + if (task == (TC_TCB *) TCD_Current_Thread) + { + + /* Task sending signals to itself. */ + + /* Clear the saved stack pointer to indicate that this is an + in line signal handler call. */ + task -> tc_saved_stack_ptr = NU_NULL; + + /* Release protection from multiple access. */ + TCT_Unprotect(); + + /* Call the signal handling shell. */ + TCC_Signal_Shell(); + } + else + { + + /* Target task must be prepared to receive the signals. */ + + /* First, insure that the target task is not in a protected + area. */ + do + { + + /* Check for protection. Remember that protection is still + in effect. */ + if (task -> tc_current_protect) + { + + /* Yes, target task is in a protected mode. Release + the protection on the scheduling list and transfer + control briefly to the target task. */ + TCT_Unprotect(); + + /* Switch to the protected task and wait until the + task is not protected. */ + TCT_Protect_Switch(task); + + /* Restore protection on the scheduling structures. */ + TCT_Protect(&TCD_System_Protect); + } + } while (task -> tc_current_protect); + + /* Copy the current status and stack pointer to the signal save + areas. */ + task -> tc_saved_status = task -> tc_status; + task -> tc_saved_stack_ptr = task -> tc_stack_pointer; + + /* Build a stack frame for the signal handling shell function. */ + TCT_Build_Signal_Frame(task); + + /* Determine if the target task is currently suspended. If it is + suspended for any other reason than a pure suspend, resume + it. */ + if ((task -> tc_status != NU_READY) && + (task -> tc_status != NU_PURE_SUSPEND)) + { + + /* Resume the target task and check for preemption. */ + if (TCC_Resume_Task(task_ptr, task -> tc_status)) + + /* Preemption needs to take place. */ + TCT_Control_To_System(); + } + } + } + + /* Release protection, no signals are currently enabled. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return a successful status. */ + return(NU_SUCCESS); +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/tcse.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,527 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* tcse.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* TC - Thread Control */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains error checking routines for the supplemental */ +/* functions in the Thread Control component. This permits easy */ +/* removal of error checking logic when it is not needed. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* TCSE_Change_Priority Change task's priority */ +/* TCSE_Change_Preemption Change task's preemption */ +/* TCSE_Change_Time_Slice Change task's time slice */ +/* TCSE_Control_Signals Enable and disable signals */ +/* TCSE_Receive_Signals Receive current signals */ +/* TCSE_Register_Signal_Handler Register a signal handler */ +/* TCSE_Send_Signals Send signals to a task */ +/* TCSE_Activate_HISR Activate an HISR */ +/* */ +/* DEPENDENCIES */ +/* */ +/* tc_extr.h Thread Control functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Created initial version 1.1 from */ +/* routines originally in core */ +/* error checking file */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-17-1997 Protected Send Signals service */ +/* from NULL Control Block pointers */ +/* creating 1.2a. (SPR220) */ +/* 03-24-1998 Released version 1.3. */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "tc_extr.h" /* Thread control functions */ + +/* Define external inner-component global data references. */ + +extern TC_TCB *TCD_Execute_Task; +extern VOID *TCD_Current_Thread; + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCSE_Change_Priority */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking for the change priority */ +/* service. If an error is detected, this service is ignored and */ +/* the requested priority is returned. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCS_Change_Priority Actual change priority */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Task control block pointer */ +/* new_priority New priority for task */ +/* */ +/* OUTPUTS */ +/* */ +/* old_priority Original task priority */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +OPTION TCSE_Change_Priority(NU_TASK *task_ptr, OPTION new_priority) +{ + +TC_TCB *task; /* Task control block ptr */ +OPTION old_priority; /* Previous priority of task */ + + + /* Move input task pointer into internal task pointer. */ + task = (TC_TCB *) task_ptr; + + /* Determine if the task pointer is valid. */ + if (task -> tc_id == TC_TASK_ID) + + /* Nothing seems to be wrong, change the priority as specified. */ + old_priority = TCS_Change_Priority(task_ptr, new_priority); + + else + + /* Copy the new priority into the old priority. */ + old_priority = new_priority; + + /* Return the previous priority. */ + return(old_priority); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCSE_Change_Preemption */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the change preemption */ +/* service. If the current thread is not a task thread, this */ +/* request is ignored. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCS_Change_Preemption Change the preemption posture*/ +/* of the calling task */ +/* */ +/* INPUTS */ +/* */ +/* preempt Preempt selection parameter */ +/* */ +/* OUTPUTS */ +/* */ +/* old_preempt Original preempt value */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +OPTION TCSE_Change_Preemption(OPTION preempt) +{ + +TC_TCB *task; /* Pointer to task */ +OPTION old_preempt; + + /* Pickup the current thread and place it in the task pointer. */ + task = (TC_TCB *) TCD_Current_Thread; + + /* Determine if the current thread is really a task thread. */ + if (task -> tc_id == TC_TASK_ID) + + /* Yes, change the preemption posture. */ + old_preempt = TCS_Change_Preemption(preempt); + + else + + /* Return the original request. */ + old_preempt = preempt; + + /* Return the previous preemption posture. */ + return(old_preempt); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCSE_Change_Time_Slice */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the change time slice */ +/* service. If the specified task pointer is invalid, this */ +/* request is ignored. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCS_Change_Time_Slice Change the time slice of the */ +/* specified task */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Task control block pointer */ +/* time_slice New time slice value */ +/* */ +/* OUTPUTS */ +/* */ +/* old_time_slice Old time slice value */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED TCSE_Change_Time_Slice(NU_TASK *task_ptr, UNSIGNED time_slice) +{ + +TC_TCB *task; /* Task control block ptr */ +UNSIGNED old_time_slice; /* Old time slice value */ + + + /* Move input task pointer into internal pointer. */ + task = (TC_TCB *) task_ptr; + + /* Determine if the task pointer is valid. */ + if (task -> tc_id == TC_TASK_ID) + + /* Yes, change the time slice. */ + old_time_slice = TCS_Change_Time_Slice(task_ptr, time_slice); + + else + + /* Return the current request. */ + old_time_slice = time_slice; + + /* Return the previous time slice value. */ + return(old_time_slice); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCSE_Control_Signals */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function checks to see if the call is being made from a */ +/* non-task thread. If so, the request is simply ignored. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCS_Control_Signals Actual control signals func */ +/* */ +/* INPUTS */ +/* */ +/* enable_signal_mask Enable signal mask */ +/* */ +/* OUTPUTS */ +/* */ +/* Previous signal enable mask */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +UNSIGNED TCSE_Control_Signals(UNSIGNED enable_signal_mask) +{ + +UNSIGNED return_mask; /* Return signal mask */ +TC_TCB *task; /* Task pointer */ + + + /* Pickup the task pointer. */ + task = (TC_TCB *) TCD_Current_Thread; + + /* Determine if the call is valid. */ + if (task -> tc_id == TC_TASK_ID) + + /* Valid request- call actual routine to control signals. */ + return_mask = TCS_Control_Signals(enable_signal_mask); + else + + /* Return a cleared mask. */ + return_mask = 0; + + /* Return the old enable mask. */ + return(return_mask); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCSE_Receive_Signals */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function determines whether or not the call is being made */ +/* from a task thread of execution. If not, the call is ignored. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCS_Receive_Signals Actual receive signals func */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* Current signals */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +UNSIGNED TCSE_Receive_Signals(VOID) +{ + +TC_TCB *task; /* Task pointer */ +UNSIGNED signals; /* Current signals */ + + /* Pickup the task pointer. */ + task = (TC_TCB *) TCD_Current_Thread; + + /* Determine if the call is valid. */ + if (task -> tc_id == TC_TASK_ID) + + /* Valid request- call actual routine to receive signals. */ + signals = TCS_Receive_Signals(); + else + + /* Return cleared signals. */ + signals = 0; + + /* Return the signals to the caller. */ + return(signals); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCSE_Register_Signal_Handler */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function determines whether or not the caller is a task. */ +/* If the caller is not a task and/or if the supplied signal */ +/* handling function pointer is NULL, an appropriate error status */ +/* is returned. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCS_Register_Signal_Handler Actual function to register */ +/* the signal handler */ +/* */ +/* INPUTS */ +/* */ +/* signal_handler Signal execution shell */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_TASK Not called from task thread */ +/* NU_INVALID_POINTER Signal handler pointer NULL */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +STATUS TCSE_Register_Signal_Handler(VOID (*signal_handler)(UNSIGNED)) +{ + +STATUS status; /* Return status */ +TC_TCB *task; /* Task pointer */ + + /* Pickup the task pointer. */ + task = (TC_TCB *) TCD_Current_Thread; + + /* Determine if the caller is a task. */ + if (task -> tc_id != TC_TASK_ID) + + /* Indicate that the caller is invalid. */ + status = NU_INVALID_TASK; + + else if (signal_handler == NU_NULL) + + /* Indicate that the signal handler is invalid. */ + status = NU_INVALID_POINTER; + + else + + /* Everything is fine, call the actual function. */ + status = TCS_Register_Signal_Handler(signal_handler); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TCSE_Send_Signals */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function checks for an invalid task. If an invalid task */ +/* is selected and error is returned. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCS_Send_Signals Actual send signal function */ +/* */ +/* INPUTS */ +/* */ +/* task_ptr Task pointer */ +/* signals Signals to send to the task */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_TASK Task pointer is invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 03-17-1997 Corrected SPR220. */ +/* */ +/*************************************************************************/ +STATUS TCSE_Send_Signals(NU_TASK *task_ptr, UNSIGNED signals) +{ + +TC_TCB *task; /* Task control block ptr */ +STATUS status; /* Completion status */ + + + /* Move input task pointer into internal pointer. */ + task = (TC_TCB *) task_ptr; + + /* Determine if the task pointer is valid. */ + if ((task != NU_NULL) && (task -> tc_id == TC_TASK_ID)) + + /* Task pointer is valid, call the actual function. */ + status = TCS_Send_Signals(task_ptr, signals); + else + + /* Task pointer is invalid, return an error status. */ + status = NU_INVALID_TASK; + + /* Return the completion status. */ + return(status); +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/tm_defs.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,125 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* tm_defs.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* TM - Timer Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains data structure definitions and constants for */ +/* the Timer Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* TM_TCB Timer control block */ +/* TM_APP_TCB Application timer control */ +/* block */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_defs.h Common service definitions */ +/* tc_defs.h Thread control definitions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "cs_defs.h" /* Common service constants */ + + +/* Check to see if the file has been included already. */ + +#ifndef TM_DEFS +#define TM_DEFS + + +/* Define constants local to this component. */ + +#define TM_TIMER_ID 0x54494d45UL +#define TM_ACTIVE 0 +#define TM_NOT_ACTIVE 1 +#define TM_EXPIRED 2 +#define TM_TASK_TIMER 0 +#define TM_APPL_TIMER 1 + +/* Define the Timer Control Block data type. */ + +typedef struct TM_TCB_STRUCT +{ + INT tm_timer_type; /* Application/Task */ + UNSIGNED tm_remaining_time; /* Remaining time */ + VOID *tm_information; /* Information pointer */ + struct TM_TCB_STRUCT + *tm_next_timer, /* Next timer in list */ + *tm_previous_timer; /* Previous timer in list*/ +} TM_TCB; + + +/* Define Application's Timer Control Block data type. */ + +typedef struct TM_APP_TCB_STRUCT +{ + CS_NODE tm_created; /* Node for linking to */ + /* created timer list */ + UNSIGNED tm_id; /* Internal TCB ID */ + CHAR tm_name[NU_MAX_NAME]; /* Timer name */ + VOID (*tm_expiration_routine)(UNSIGNED); /* Expiration function */ + UNSIGNED tm_expiration_id; /* Expiration ID */ + BOOLEAN tm_enabled; /* Timer enabled flag */ + +#if PAD_3 + DATA_ELEMENT tc_padding[PAD_3]; +#endif + + UNSIGNED tm_expirations; /* Number of expirations */ + UNSIGNED tm_initial_time; /* Initial time */ + UNSIGNED tm_reschedule_time; /* Reschedule time */ + TM_TCB tm_actual_timer; /* Actual timer internals*/ +} TM_APP_TCB; + + +/* Include this file here, since it contains references to the timer definition + structure that is defined by this file. */ + +#include "tc_defs.h" + +#endif /* TM_DEFS */ + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/tm_extr.h Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,135 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* tm_extr.h Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* TM - Timer Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains function prototypes of all functions */ +/* accessible to other components. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* tm_defs.h Timer Management constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Moved include files outside of */ +/* the file #ifndef to allow the */ +/* use of actual data structures, */ +/* changed function names due to */ +/* changes in file structure, */ +/* removed protection pointer */ +/* parameter, added several new */ +/* target functions, changed */ +/* prototypes, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ + +#include "tm_defs.h" /* Include TM constants */ + + +/* Check to see if the file has been included already. */ + +#ifndef TM_EXTR +#define TM_EXTR + + +/* Initialization functions. */ + +VOID TMI_Initialize(VOID); + + +/* Error checking for supplemental functions. */ + +STATUS TMSE_Create_Timer(NU_TIMER *timer_ptr, CHAR *name, + VOID (*expiration_routine)(UNSIGNED), UNSIGNED id, + UNSIGNED initial_time, UNSIGNED reschedule_time, + OPTION enable); +STATUS TMSE_Delete_Timer(NU_TIMER *timer_ptr); +STATUS TMSE_Reset_Timer(NU_TIMER *timer_ptr, + VOID (*expiration_routine)(UNSIGNED), + UNSIGNED initial_time, UNSIGNED reschedule_time, + OPTION enable); +STATUS TMSE_Control_Timer(NU_TIMER *timer_ptr, OPTION enable); + + +/* Supplemental processing functions. */ + +STATUS TMS_Create_Timer(NU_TIMER *timer_ptr, CHAR *name, + VOID (*expiration_routine)(UNSIGNED), UNSIGNED id, + UNSIGNED initial_time, UNSIGNED reschedule_time, + OPTION enable); +STATUS TMS_Delete_Timer(NU_TIMER *timer_ptr); +STATUS TMS_Reset_Timer(NU_TIMER *timer_ptr, + VOID (*expiration_routine)(UNSIGNED), + UNSIGNED initial_time, UNSIGNED reschedule_timer, + OPTION enable); +STATUS TMS_Control_Timer(NU_TIMER *timer_ptr, OPTION enable); + + +/* Core processing functions. */ + +VOID TMC_Init_Task_Timer(TM_TCB *timer, VOID *information); +VOID TMC_Start_Task_Timer(TM_TCB *timer, UNSIGNED time); +VOID TMC_Stop_Task_Timer(TM_TCB *timer); + + +/* Information retrieval funtions. */ + +UNSIGNED TMF_Established_Timers(VOID); +STATUS TMF_Timer_Information(NU_TIMER *timer_ptr, CHAR *name, + OPTION *enable, UNSIGNED *expirations, UNSIGNED *id, + UNSIGNED *initial_time, UNSIGNED *reschedule_time); +UNSIGNED TMF_Timer_Pointers(NU_TIMER **pointer_list, + UNSIGNED maximum_pointers); + +/* Target dependent functions. */ + +VOID TMT_Set_Clock(UNSIGNED new_value); +UNSIGNED TMT_Retrieve_Clock(VOID); +NU_TASK *TMT_Retrieve_TS_Task(VOID); +VOID TMT_Adjust_Timer(UNSIGNED new_value); + +#endif + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/tmc.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,944 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* tmc.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* TM - Timer Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the core routines for the timer management */ +/* component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* TMC_Init_Task_Timer Initialize task timer */ +/* TMC_Start_Task_Timer Start task timer */ +/* TMC_Stop_Task_Timer Stop task timer */ +/* TMC_Start_Timer Actually start a timer */ +/* TMC_Stop_Timer Actually stop a timer */ +/* TMC_Timer_HISR Timer High-Level Interrupt */ +/* Service Routine (HISR) */ +/* TMC_Timer_Expiration Timer expiration function */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* tm_extr.h Timer functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected the following problems */ +/* - Moved sleep, timeout, and */ +/* application timer expiration */ +/* processing to system timer */ +/* HISR. Removed timer task */ +/* logic */ +/* - Corrected a disable timer */ +/* problem that caused a delay */ +/* in subsequent timer */ +/* expiration */ +/* - Corrected the application */ +/* timer ID returned by the */ +/* timer information service */ +/* Corrected the loop to return */ +/* all application timer */ +/* pointers */ +/* - Corrected timer expiration */ +/* while accessing from an LISR */ +/* - Using the task time slice ptr */ +/* instead of the time slice */ +/* state flag */ +/* Modifications resulted in */ +/* version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Moved non-core functions into */ +/* supplemental files, modified */ +/* protection logic to use system */ +/* protect mechanism, removed the */ +/* disable timer logic in start */ +/* timer, insured valid time- */ +/* slice task pointer, added */ +/* register logic, resulting */ +/* in version 1.1 */ +/* */ +/* 3-18-1994 Verified version 1.1 */ +/* 08-25-95 Made the following changes */ +/* */ +/* +INT type = 0; Type of expiration */ +/* +VOID *pointer = NU_NULL; Pointer type */ +/* +UNSIGNED id = 0; Application timer ID */ +/* -INT type; Type of expiration */ +/* -VOID *pointer; Pointer type */ +/* -UNSIGNED id; Application timer ID */ +/* Expiration routine ptr */ +/* +VOID (*expiration_routine)(UNSIGNED)= NU_NULL; */ +/* -VOID (*expiration_routine)(UNSIGNED); */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "tm_extr.h" /* Timer functions */ +#include "hi_extr.h" /* History functions */ + + +/* Define external inner-component global data references. */ + +extern TM_TCB *TMD_Active_Timers_List; +extern INT TMD_Active_List_Busy; +extern UNSIGNED TMD_System_Clock; +extern UNSIGNED TMD_Timer_Start; +extern UNSIGNED TMD_Timer; +extern INT TMD_Timer_State; +extern UNSIGNED TMD_Time_Slice; +extern TC_TCB *TMD_Time_Slice_Task; +extern INT TMD_Time_Slice_State; + + +/* Define internal function prototypes. */ + +VOID TMC_Start_Timer(TM_TCB *timer, UNSIGNED time); +VOID TMC_Stop_Timer(TM_TCB *timer); +VOID TMC_Timer_Expiration(VOID); +UNSIGNED TMT_Read_Timer(VOID); +VOID TMT_Enable_Timer(UNSIGNED time); +VOID TMT_Disable_Timer(VOID); + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TMC_Init_Task_Timer */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for initializing the supplied task */ +/* timer. This routine must be called from Supervisor mode in a */ +/* Supervisor/User mode switching kernel. */ +/* */ +/* CALLED BY */ +/* */ +/* TCC_Create_Task Task create function */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* INPUTS */ +/* */ +/* timer Timer control block pointer */ +/* information Information pointer - always */ +/* the task pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* */ +/*************************************************************************/ +VOID TMC_Init_Task_Timer(TM_TCB *timer, VOID *information) +{ + + /* Initialize the task timer. */ + timer -> tm_timer_type = TM_TASK_TIMER; + timer -> tm_information = information; + timer -> tm_next_timer = NU_NULL; + timer -> tm_previous_timer = NU_NULL; +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TMC_Start_Task_Timer */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for starting a task timer. Note */ +/* that there are some special protection considerations since */ +/* this function is called from the task control component. This */ +/* routine must be called from Supervisor mode in a Supervisor/User */ +/* mode switching kernel. */ +/* */ +/* CALLED BY */ +/* */ +/* TCC_Suspend_Task Suspend task with a timeout */ +/* */ +/* CALLS */ +/* */ +/* TMC_Start_Timer Start the timer */ +/* */ +/* INPUTS */ +/* */ +/* timer Timer control block pointer */ +/* time Time associated with timer */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Removed protection logic since */ +/* system protect is in force at */ +/* the time this function is */ +/* called, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +VOID TMC_Start_Task_Timer(TM_TCB *timer, UNSIGNED time) +{ + + /* Start the specified timer. */ + TMC_Start_Timer(timer, time); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TMC_Stop_Task_Timer */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for stopping a task timer. Note */ +/* that there are some special protection considerations since */ +/* this function is called from the task control component. This */ +/* routine must be called from Supervisor mode in a Supervisor/User */ +/* mode switching kernel. */ +/* */ +/* CALLED BY */ +/* */ +/* TCC_Resume_Task Resume task function */ +/* TCC_Terminate_Task Terminate task function */ +/* */ +/* CALLS */ +/* */ +/* TMC_Stop_Timer Stop the timer */ +/* */ +/* INPUTS */ +/* */ +/* timer Timer control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Removed protection logic since */ +/* system protect is in force at */ +/* the time this function is */ +/* called, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +VOID TMC_Stop_Task_Timer(TM_TCB *timer) +{ + + /* Stop the specified timer - if it is still active. */ + if (timer -> tm_next_timer) + + TMC_Stop_Timer(timer); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TMC_Start_Timer */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for starting both application and */ +/* task timers. This routine must be called from Supervisor mode */ +/* in a Supervisor/User mode switching kernel. */ +/* */ +/* CALLED BY */ +/* */ +/* TMC_Control_Timer Control application timer */ +/* TMC_Start_Task_Timer Start task timer */ +/* */ +/* CALLS */ +/* */ +/* TMT_Read_Timer Read current timer counter */ +/* TMT_Adjust_Timer Adjust the count-down timer */ +/* TMT_Enable_Timer Enable count-down timer */ +/* */ +/* INPUTS */ +/* */ +/* timer Timer control block pointer */ +/* time Time associated with timer */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Added logic to check for timer */ +/* expiration before or during */ +/* another LISR's access, */ +/* resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Removed disable timer logic to */ +/* insure there is no timer loss, */ +/* added register logic, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +VOID TMC_Start_Timer(TM_TCB *timer, UNSIGNED time) +{ + +R1 TM_TCB *list_ptr; /* Working pointer timer ptr */ +UNSIGNED elapsed; /* Elapsed time variable */ +INT done; /* Search finished flag */ + + + /* Note that protection over the active timer list is in force when this + function is called. */ + + /* Determine if the active list is empty. */ + if (TMD_Active_Timers_List == NU_NULL) + { + + /* Place the timer on an empty list. */ + timer -> tm_next_timer = timer; + timer -> tm_previous_timer = timer; + + /* Link the timer to the list head. */ + TMD_Active_Timers_List = timer; + + /* Setup the actual count-down timer structures. */ + TMD_Timer_Start = time; + timer -> tm_remaining_time = time; + + + /* BUG FIX FOR NU_RESET WITH INITIAL TIME OF 0 */ + /* Determine if there is any time remaining on the timer. + If so, enable the timer. Otherwise, the Timer HISR is + already pending, so skip starting the timer again. */ + + if (time != 0) + /* Start the actual count-down timer. */ + TMT_Enable_Timer(TMD_Timer_Start); + else + TMD_Timer_State = TM_EXPIRED; + + } + else + { + + /* Place the new timer into the list. */ + + /* Pickup the head of the list. */ + list_ptr = TMD_Active_Timers_List; + + /* Determine if the timer is being added while the timer + expiration task is running. If so, don't attempt to adjust + the expiration list. If not, adjust the list. */ + if (!TMD_Active_List_Busy) + { + + /* Calculate the elapsed amount of time from the last timer + request. */ + elapsed = TMD_Timer_Start - TMT_Read_Timer(); + + /* Adjust the first entry in the timer list and the timer + start value accordingly. */ + TMD_Timer_Start = TMD_Timer_Start - elapsed; + + /* Make sure the remaining time is never below zero. */ + if (list_ptr -> tm_remaining_time > elapsed) + { + list_ptr -> tm_remaining_time = list_ptr -> tm_remaining_time + - elapsed; + } + else + { + list_ptr -> tm_remaining_time = 0; + } + + + } + + /* At this point the timer list is accurate again. Find the + appropriate place on the timer list for the new timer. */ + + /* Determine where to place the timer in the list. */ + done = NU_FALSE; + do + { + + /* Determine if the timer belongs before the current timer + pointed to by list_ptr. */ + if (time < list_ptr -> tm_remaining_time) + { + + /* Update the time of the next timer. */ + list_ptr -> tm_remaining_time = + list_ptr -> tm_remaining_time - time; + + /* Determine if an insertion at the head of the list is + present. */ + if (list_ptr == TMD_Active_Timers_List) + + /* Move the list head to the new timer. */ + TMD_Active_Timers_List = timer; + + /* Set the done flag to end the search. */ + done = NU_TRUE; + } + else + { + + /* Decrement the time by the remaining value of each timer in + the list. In this way, the list never has to be searched + again. */ + time = time - list_ptr -> tm_remaining_time; + + /* Move the list pointer to the next timer in the list. */ + list_ptr = list_ptr -> tm_next_timer; + + /* Check to see if the list has wrapped around. */ + if (list_ptr == TMD_Active_Timers_List) + + /* Searching is done. */ + done = NU_TRUE; + } + } while (!done); + + /* Link the new timer into the list. */ + timer -> tm_next_timer = list_ptr; + timer -> tm_previous_timer = list_ptr -> tm_previous_timer; + (list_ptr -> tm_previous_timer) -> tm_next_timer = timer; + list_ptr -> tm_previous_timer = timer; + + /* Update the remaining time parameter. */ + timer -> tm_remaining_time = time; + + /* Determine if a new timer should be started. */ + if (!TMD_Active_List_Busy) + { + + /* Calculate the new timer expiration. */ + time = TMD_Active_Timers_List -> tm_remaining_time; + + /* Determine if the new expiration is less than the current + time, if any. If not, let already started time expire. */ + if (time <= TMD_Timer_Start) + { + + /* Setup for a smaller timer expiration. */ + TMD_Timer_Start = time; + + /* Determine if there is any time remaining on the timer in + the front of the list. If so, adjust the timer. + Otherwise, the Timer HISR is already pending, so skip + starting the timer again. */ + if (TMD_Timer_Start) + + /* Still some remaining time, adjust the timer. */ + TMT_Adjust_Timer(TMD_Timer_Start); + else + + /* Indicate that the task and application timer has + expired. */ + TMD_Timer_State = TM_EXPIRED; + } + } + } +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TMC_Stop_Timer */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for stopping both application and */ +/* task timers. This routine must be called from Supervisor mode */ +/* in a Supervisor/User mode switching kernel. */ +/* */ +/* CALLED BY */ +/* */ +/* TMC_Control_Timer Control application timer */ +/* TMC_Stop_Task_Timer Start task timer */ +/* */ +/* CALLS */ +/* */ +/* TMT_Disable_Timer Disable the count-down timer */ +/* */ +/* INPUTS */ +/* */ +/* timer Timer control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected a problem associated */ +/* with stopping the last timer */ +/* on the active list, resulting */ +/* in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* */ +/*************************************************************************/ +VOID TMC_Stop_Timer(TM_TCB *timer) +{ + + /* Note that the active timer list is already under protection. */ + + /* If the next neighbor of the timer that needs to be stopped is not the + head of the timer list, add the remaining time field to the remaining + time of the next neighbor. */ + if ((timer -> tm_next_timer) != TMD_Active_Timers_List) + + /* Adjust the next neighbor's remaining time field. */ + (timer -> tm_next_timer) -> tm_remaining_time = + (timer -> tm_next_timer) -> tm_remaining_time + + timer -> tm_remaining_time; + + /* Unlink the timer from the active list. */ + if (timer -> tm_next_timer == timer) + { + /* Only timer on the list. */ + TMD_Active_Timers_List = NU_NULL; + + /* Disable the timer. */ + TMT_Disable_Timer(); + } + else + { + + /* More than one timer on the list. */ + (timer -> tm_previous_timer) -> tm_next_timer = timer -> tm_next_timer; + (timer -> tm_next_timer) -> tm_previous_timer = + timer -> tm_previous_timer; + + /* Determine if the timer is at the head of the list. */ + if (TMD_Active_Timers_List == timer) + + /* Yes, move the head pointer to the next timer. */ + TMD_Active_Timers_List = timer -> tm_next_timer; + } + + /* Clear the timer's next and previous pointers. */ + timer -> tm_next_timer = NU_NULL; + timer -> tm_previous_timer = NU_NULL; +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TMC_Timer_HISR */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for High-Level interrupt processing */ +/* of a timer expiration. If an application timer has expired, */ +/* the timer expiration function is called. Otherwise, if the */ +/* time-slice timer has expired, time-slice processing is invoked. */ +/* */ +/* CALLED BY */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* TCC_Time_Slice Task time-slice processing */ +/* TMC_Timer_Expiration Timer expiration processing */ +/* TMT_Retrieve_TS_Task Retrieve time-sliced task ptr*/ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Added sleep, timeout, and */ +/* application timer expiration */ +/* processing to the timer HISR, */ +/* using time slice task pointer */ +/* instead of state flag, */ +/* resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Modified function interface to */ +/* TCC_Time_Slice, added logic to */ +/* insure valid pointer for some */ +/* ports, resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +VOID TMC_Timer_HISR(VOID) +{ + +NU_TASK *task; /* Time slice task. */ + + + /* Determine if the task timer has expired. */ + if (TMD_Timer_State == TM_EXPIRED) + + /* Resume the timer task. */ + TMC_Timer_Expiration(); + + /* Determine if the time-slice timer has expired. */ + task = TMT_Retrieve_TS_Task(); + if (task) + { + NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode + + Note that this HISR function can make the switch to supervisor mode + this is only possible because the code lives within the kernel */ + NU_SUPERVISOR_MODE(); + + /* Reset the time-slice state. */ + TMD_Time_Slice_State = TM_NOT_ACTIVE; + + /* Process the time-slice. */ + TCC_Time_Slice(task); + + /* Clear the time slice task pointer. */ + TMD_Time_Slice_Task = NU_NULL; + + /* Return to user mode */ + NU_USER_MODE(); + } +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TMC_Timer_Expiration */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for processing all task timer */ +/* expirations. This includes application timers and basic task */ +/* timers that are used for task sleeping and timeouts. */ +/* */ +/* CALLED BY */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* expiration_function Application specified timer */ +/* expiration function */ +/* TCC_Task_Timeout Task timeout function */ +/* TCT_System_Protect Protect active timer list */ +/* TCT_Unprotect Release protection of list */ +/* TMC_Stop_Timer Stop timer */ +/* TMC_Start_Timer Start timer */ +/* TMT_Disable_Timer Disable timer */ +/* TMT_Enable_Timer Enable timer */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* None */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Changed from TMC_Timer_Task to */ +/* TMC_Timer_Expiration, */ +/* resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Modified function interface to */ +/* TCC_Task_Timeout, changed */ +/* protection logic to use system */ +/* protetion, added register */ +/* logic, resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 08-25-95 Made the following changes */ +/* */ +/* +INT type = 0; Type of expiration */ +/* +VOID *pointer = NU_NULL; Pointer type */ +/* +UNSIGNED id = 0; Application timer ID */ +/* -INT type; Type of expiration */ +/* -VOID *pointer; Pointer type */ +/* -UNSIGNED id; Application timer ID */ +/* Expiration routine ptr */ +/* +VOID (*expiration_routine)(UNSIGNED)= NU_NULL; */ +/* -VOID (*expiration_routine)(UNSIGNED); */ +/* */ +/*************************************************************************/ +VOID TMC_Timer_Expiration(VOID) +{ + +R1 TM_TCB *timer; /* Pointer to timer */ +R2 TM_APP_TCB *app_timer; /* Pointer to app timer */ +INT done; /* Expiration completion */ +INT type = 0; /* Type of expiration */ +VOID *pointer = NU_NULL; /* Pointer type */ +UNSIGNED id = 0; /* Application timer ID */ + /* Expiration routine ptr */ +VOID (*expiration_routine)(UNSIGNED)= NU_NULL; +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Use system protect to protect the active timer list. */ + TCT_System_Protect(); + + /* Reset the timer state flag. */ + TMT_Disable_Timer(); + + /* Set the busy flag to indicate that the list is being processed. */ + TMD_Active_List_Busy = NU_TRUE; + + /* Update the head of the list with the timer expiration + value. */ + timer = TMD_Active_Timers_List; + if (timer) + { + + /* Adjust the active timer's remaining time value. Note that + TMD_Timer_Start is never greater than the value in the first + timer location. */ + if (timer -> tm_remaining_time > TMD_Timer_Start) + + /* Timer has not expired. Simply subtract the last timer + value. */ + timer -> tm_remaining_time = timer -> tm_remaining_time - + TMD_Timer_Start; + else + + /* Clear the remaining time field of the timer. */ + timer -> tm_remaining_time = 0; + } + + /* Release protection, but keep the busy flag set to prevent + activating new timers. */ + TCT_Unprotect(); + + + /* Find expired timers. Note that the expired timers have values of + 0 in the remaining time field. */ + done = NU_FALSE; + do + { + + /* Protect against list access. */ + TCT_System_Protect(); + + /* Pickup the head of the active list. */ + timer = TMD_Active_Timers_List; + + /* Determine if the timer now at the head of the list has + expired. Processing continues until the list is empty or + until a non-expired timer is at the front of the list. */ + if ((timer) && (timer -> tm_remaining_time == 0)) + { + + /* Timer has expired. Determine which type of timer has + expired. */ + if (timer -> tm_timer_type == TM_APPL_TIMER) + { + + /* Application timer has expired. */ + type = TM_APPL_TIMER; + + /* Pickup the pointer to the application timer control + block. */ + app_timer = (TM_APP_TCB *) timer -> tm_information; + + /* Increment the number of expirations. */ + app_timer -> tm_expirations++; +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTimer(RT_PROF_APP_TIMER_EXPIRED,app_timer,RT_PROF_OK); +#endif + + /* Move the expiration information into local variables + in case they get corrupted before this expiration can + be processed. Expirations are processed without the + list protection in force. */ + id = app_timer -> tm_expiration_id; + expiration_routine = app_timer -> tm_expiration_routine; + + /* Clear the enabled flag and remove the timer from the + list. */ + app_timer -> tm_enabled = NU_FALSE; + TMC_Stop_Timer(timer); + + /* Determine if this timer should be started again. */ + if (app_timer -> tm_reschedule_time) + { + + /* Timer needs to be rescheduled. */ + + /* Setup the enable flag to show that the timer is + enabled. */ + app_timer -> tm_enabled = NU_TRUE; + + /* Call the start timer function to actually enable + the timer. This also puts it in the proper place + on the list. */ + TMC_Start_Timer(timer,app_timer -> tm_reschedule_time); + } + } + else + { + + /* Task timer has expired (sleeps and timeouts). */ + type = TM_TASK_TIMER; + + /* Remove the timer from the list. */ + TMC_Stop_Timer(timer); + + /* Save-off the task control block pointer. */ + pointer = timer -> tm_information; + } + } + else + + /* Processing is now complete- no more expired timers on the + list. */ + done = NU_TRUE; + + /* Release protection of active list. */ + TCT_Unprotect(); + + /* Determine if a timer expiration needs to be finished. Note + that the actual expiration processing is done with protection + disabled. This prevents deadlock situations from arising. */ + if (!done) + { + + /* Determine which type of timer has expired. */ + if (type == TM_APPL_TIMER) + + /* Call application timer's expiration function. */ + (*(expiration_routine)) (id); + else + + /* Call the task timeout function in the thread control + function. */ + TCC_Task_Timeout((NU_TASK *) pointer); + } + } while (!done); + + /* Protect the active list again. */ + TCT_System_Protect(); + + /* Clear the busy flag to indicate that list processing is complete. */ + TMD_Active_List_Busy = NU_FALSE; + + /* Determine if a new timer should be enabled. */ + if (TMD_Active_Timers_List) + { + + /* Yes, a new timer should be activated. */ + + /* Pickup the new timer expiration value. */ + TMD_Timer_Start = TMD_Active_Timers_List -> tm_remaining_time; + + /* Start the new timer. */ + TMT_Enable_Timer(TMD_Timer_Start); + } + + /* Release protection of the active timer list. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); +} + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/tmd.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,200 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* tmd.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* TM - Timer Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains global data structures for use within the */ +/* timer management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* TMD_Created_Timers_List Pointer to the linked-list */ +/* of created application */ +/* timers */ +/* TMD_Total_Timers Total number of created */ +/* application timers */ +/* TMD_Active_Timers_List Pointer to the linked-list */ +/* of active timers. */ +/* TMD_Active_List_Busy Flag indicating that the */ +/* active timer list is in use*/ +/* TMD_Created_List_Protect Created timer list protect */ +/* structure */ +/* TMD_System_Clock System clock */ +/* TMD_Timer_Start Starting value of timer */ +/* TMD_Timer Timer count-down value */ +/* TMD_Timer_State State of timer */ +/* TMD_Time_Slice Time slice count-down value */ +/* TMD_Time_Slice_Task Pointer to task to time-slice*/ +/* TMD_Time_Slice_State State of time slice */ +/* TMD_HISR Timer HISR control block */ +/* TMD_HISR_Stack_Ptr Pointer to HISR stack area */ +/* TMD_HISR_Stack_Size Size of HISR stack area */ +/* TMD_HISR_Priority Priority of timer HISR */ +/* */ +/* FUNCTIONS */ +/* */ +/* None */ +/* */ +/* DEPENDENCIES */ +/* */ +/* tm_defs.h Timer Management constants */ +/* tc_defs.h Thread Control constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Removed timer task structures, */ +/* making version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Removed active list protect data */ +/* structure since system protect */ +/* is now used, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + +#include "tm_defs.h" /* Timer constants */ + + +/* TMD_Created_Timers_List is the head pointer of the linked list of + created application timers. If the list is NU_NULL, there are no timers + currently created. */ + +CS_NODE *TMD_Created_Timers_List; + + +/* TMD_Total_Timers contains the total number of created application timers + in the system. */ + +UNSIGNED TMD_Total_Timers; + + +/* TMD_Active_Timers_List is the head pointer of the linked list of active + timers. This includes both the application timers and the system timers + used for task sleeping and timeouts. If the list is NU_NULL, there are + no timers currently active. */ + +TM_TCB *TMD_Active_Timers_List; + + +/* TMD_Active_List_Busy is a flag that indicates that the active timer list + is being processed. This is used to prevent multiple updates to the + active timer list. */ + +INT TMD_Active_List_Busy; + + +/* TMD_Created_List_Protect is used to protect the created application timers + list from multiple accesses. */ + +TC_PROTECT TMD_Created_List_Protect; + + +/* TMD_System_Clock is a continually incrementing clock. One is added to + the clock each timer interrupt. */ + +UNSIGNED TMD_System_Clock; + + +/* TMD_Timer_Start represents the starting value of the last set timer + request. */ + +UNSIGNED TMD_Timer_Start; + + +/* TMD_Timer is a count-down timer that is used to represent the smallest + active timer value in the system. Once this counter goes to zero, a + timer has expired. */ + +UNSIGNED TMD_Timer; + + +/* TMD_Timer_State indicates the state of the timer variable. If the state + is active, the timer counter is decremented. If the state is expired, + the timer HISR and timer task are initiated to process the expiration. If + the state indicates that the timer is not-active, the timer counter is + ignored. */ + +INT TMD_Timer_State; + + +/* TMD_Time_Slice contains the count-down value for the currently executing + task's time slice. When this value goes to zero, time slice processing + is started. */ + +UNSIGNED TMD_Time_Slice; + + +/* TMD_Time_Slice_Task is a pointer to the task to time-slice. This pointer + is built in the portion of the timer interrupt that determines if a time- + slice timer has expired. */ + +TC_TCB *TMD_Time_Slice_Task; + + +/* TMD_Time_Slice_State indicates the state of the time slice variable. If + the state is active, the time slice counter is decremented. If the + state is expired, the timer HISR is initiated to process the expiration. + If the state indicates that the time slice is not-active, the time slice + counter is ignored. */ + +INT TMD_Time_Slice_State; + + +/* TMD_HISR is the timer HISR's control block. */ + +TC_HCB TMD_HISR; + + +/* TMD_HISR_Stack_Ptr points to the memory area reserved for the timer HISR. + Note that this is setup in INT_Initialize. */ + +VOID *TMD_HISR_Stack_Ptr; + + +/* TMD_HISR_Stack_Size represents the size of the allocated timer HISR stack. + Note that this is setup in INT_Initialize. */ + +UNSIGNED TMD_HISR_Stack_Size; + + +/* TMD_HISR_Priority indicates the priority of the timer HISR. Priorities + range from 0 to 2, where priority 0 is the highest. Note that this is + also initialized in INT_Initialize. */ + +INT TMD_HISR_Priority; + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/tmf.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,489 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* tmf.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* TM - Timer Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains information (fact) routines for the Timer */ +/* Management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* TMF_Established_Timers Number of established timers */ +/* TMF_Timer_Pointers Return list of application */ +/* timer pointers */ +/* TMF_Timer_Information Return information about the */ +/* application timer */ +/* */ +/* TMF_Get_Remaining_Time Return remaining timer until */ +/* a timer expires */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* tm_extr.h Timer functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Created initial version 1.1 from */ +/* previous version of TMC.C */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 11-18-1996 Protected Informational service */ +/* from NULL Control Block pointers */ +/* creating 1.2a. (SPR220) */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "tm_extr.h" /* Timer functions */ +#include "hi_extr.h" /* History functions */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *TMD_Created_Timers_List; +extern UNSIGNED TMD_Total_Timers; +extern TM_TCB *TMD_Active_Timers_List; +extern INT TMD_Active_List_Busy; +extern TC_PROTECT TMD_Created_List_Protect; + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TMF_Established_Timers */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the current number of established */ +/* timers. Timers previously deleted are no longer considered */ +/* established. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* */ +/* INPUTS */ +/* */ +/* None */ +/* */ +/* OUTPUTS */ +/* */ +/* TMD_Total_Timers Number of established */ +/* timers */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED TMF_Established_Timers(VOID) +{ + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Return the number of established timers. */ + return(TMD_Total_Timers); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TMF_Timer_Pointers */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function builds a list of timer pointers, starting at the */ +/* specified location. The number of timer pointers placed in */ +/* the list is equivalent to the total number of timers or the */ +/* maximum number of pointers specified in the call. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect created list */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* pointer_list Pointer to the list area */ +/* maximum_pointers Maximum number of pointers */ +/* */ +/* OUTPUTS */ +/* */ +/* pointers Number of timers placed */ +/* in the list */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected problem in pointer */ +/* retrieval loop, resulting in */ +/* version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Changed function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +UNSIGNED TMF_Timer_Pointers(NU_TIMER **pointer_list, + UNSIGNED maximum_pointers) +{ + +CS_NODE *node_ptr; /* Pointer to each TCB */ +UNSIGNED pointers; /* Number of pointers in list*/ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Initialize the number of pointers returned. */ + pointers = 0; + + /* Protect against access to the list of created timers. */ + TCT_Protect(&TMD_Created_List_Protect); + + /* Loop until all timer pointers are in the list or until the maximum + list size is reached. */ + node_ptr = TMD_Created_Timers_List; + while ((node_ptr) && (pointers < maximum_pointers)) + { + + /* Place the node into the destination list. */ + *pointer_list++ = (NU_TIMER *) node_ptr; + + /* Increment the pointers variable. */ + pointers++; + + /* Position the node pointer to the next node. */ + node_ptr = node_ptr -> cs_next; + + /* Determine if the pointer is at the head of the list. */ + if (node_ptr == TMD_Created_Timers_List) + + /* The list search is complete. */ + node_ptr = NU_NULL; + } + + /* Release protection against access to the list of created timers. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the number of pointers in the list. */ + return(pointers); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TMF_Timer_Information */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns information about the specified timer. */ +/* However, if the supplied timer pointer is invalid, the */ +/* function simply returns an error status. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_System_Protect Protect active timer */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* timer_ptr Pointer to the timer */ +/* name Destination for the name */ +/* enable Destination for the enable */ +/* posture */ +/* expirations Destination for the total */ +/* number of expirations */ +/* id Destination for the timer id */ +/* initial_time Destination for the initial */ +/* time */ +/* reschedule_time Destination for the */ +/* reschedule time */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If a valid timer pointer */ +/* is supplied */ +/* NU_INVALID_TIMER If timer pointer invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Corrected problem that caused an */ +/* invalid application timer ID */ +/* to be returned to the caller, */ +/* resulting in version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Changed function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 11-18-1996 Corrected SPR220. */ +/* */ +/*************************************************************************/ +STATUS TMF_Timer_Information(NU_TIMER *timer_ptr, CHAR *name, + OPTION *enable, UNSIGNED *expirations, UNSIGNED *id, + UNSIGNED *initial_time, UNSIGNED *reschedule_time) +{ + +TM_APP_TCB *timer; /* Timer control block ptr */ +INT i; /* Working integer variable */ +STATUS completion; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input timer pointer into internal pointer. */ + timer = (TM_APP_TCB *) timer_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + + /* Protect the active list. */ + TCT_System_Protect(); + + /* Determine if this timer ID is valid. */ + if ((timer != NU_NULL) && (timer -> tm_id == TM_TIMER_ID)) + { + + /* The timer pointer is valid. Reflect this in the completion + status and fill in the actual information. */ + completion = NU_SUCCESS; + + /* Copy the timer's name. */ + for (i = 0; i < NU_MAX_NAME; i++) + *name++ = timer -> tm_name[i]; + + /* Determine if the timer is enabled or disabled. */ + if (timer -> tm_enabled) + + *enable = NU_ENABLE_TIMER; + else + + *enable = NU_DISABLE_TIMER; + + /* Fill in the remaining information. */ + *expirations = timer -> tm_expirations; + *id = timer -> tm_expiration_id; + *initial_time = timer -> tm_initial_time; + *reschedule_time = timer -> tm_reschedule_time; + } + else + + /* Indicate that the timer pointer is invalid. */ + completion = NU_INVALID_TIMER; + + /* Release protection. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the appropriate completion status. */ + return(completion); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TMF_Get_Remaining_Time */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the remaining time before expiration for */ +/* the specified timer. */ +/* */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TCT_System_Protect Protect active timer */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* timer_ptr Pointer to the timer */ +/* */ +/* OUTPUTS */ +/* */ +/* remaining_time time until timer expiration */ +/* */ +/* NU_INVALID_TIMER If timer pointer invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 07-02-1998 Created service call */ +/* */ +/*************************************************************************/ + + +STATUS TMF_Get_Remaining_Time(NU_TIMER *timer_ptr, UNSIGNED *remaining_time) +{ +R1 TM_APP_TCB *timer; + TM_TCB *real_TCB; + TM_TCB *list_ptr; + INT done = 0; + STATUS status; + NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Protect against simultaneous access to the active timers list*/ + TCT_System_Protect(); + + list_ptr = TMD_Active_Timers_List; + + /* Get the application timer Control Block */ + timer = (TM_APP_TCB*) timer_ptr; + + + /* Determine if this timer ID is valid. */ + if ((timer != NU_NULL) && (timer -> tm_id == TM_TIMER_ID)) + { + /* The timer pointer is valid. Reflect this in the completion + status and fill in the actual information. */ + status = NU_SUCCESS; + + /* Get the actual timer Control block */ + real_TCB = &(timer->tm_actual_timer); + + if (list_ptr == real_TCB) + *remaining_time = list_ptr -> tm_remaining_time; + else + { + if( list_ptr == NU_NULL) /* in case no active timers exist */ + *remaining_time = 0; + else + { + + *remaining_time = list_ptr -> tm_remaining_time; + + do + { + /* Move the list pointer to the next timer in the list. */ + list_ptr = list_ptr -> tm_next_timer; + + *remaining_time += list_ptr -> tm_remaining_time; + + /* Check to see if we have gotten to the specified timer yet */ + if (list_ptr == real_TCB) + /* Searching is done. */ + done = NU_TRUE; + + }while (!done); + } + } + } + else + /* Indicate that the timer pointer is invalid. */ + status = NU_INVALID_TIMER; + + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + return (status); +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/tmi.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,234 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* tmi.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* TM - Timer Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the initialization routine for the timer */ +/* management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* TMI_Initialize Timer Management Initialize */ +/* */ +/* DEPENDENCIES */ +/* */ +/* tc_extr.h Task function interfaces */ +/* er_extr.h Error handling function */ +/* tm_defs.h Timer component constants */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Removed timer task creation, */ +/* cleared the ID of the HISR */ +/* control block, and casted the */ +/* HISR priority, resulting in */ +/* version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Changed names of HISR create */ +/* function, removed reference to */ +/* timer list protect since it */ +/* was deleted, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "tc_extr.h" /* Task control functions */ +#include "er_extr.h" /* Error handling function */ +#include "tm_defs.h" /* Timer constants */ +#include "tm_extr.h" /* Timer interfaces */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *TMD_Created_Timers_List; +extern UNSIGNED TMD_Total_Timers; +extern TM_TCB *TMD_Active_Timers_List; +extern INT TMD_Active_List_Busy; +extern TC_PROTECT TMD_Created_List_Protect; +extern UNSIGNED TMD_System_Clock; +extern UNSIGNED TMD_Timer; +extern INT TMD_Timer_State; +extern UNSIGNED TMD_Time_Slice; +extern TC_TCB *TMD_Time_Slice_Task; +extern INT TMD_Time_Slice_State; +extern TC_HCB TMD_HISR; +extern VOID *TMD_HISR_Stack_Ptr; +extern UNSIGNED TMD_HISR_Stack_Size; +extern INT TMD_HISR_Priority; + + +/* Define inner-component function prototypes. */ + +VOID TMC_Timer_HISR(VOID); + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TMI_Initialize */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function initializes the data structures that control the */ +/* operation of the timer component (TM). There are no application */ +/* timers created initially. This routine must be called from */ +/* Supervisor mode in Supervisor/User mode switching kernels. */ +/* */ +/* CALLED BY */ +/* */ +/* INC_Initialize System initialization */ +/* */ +/* CALLS */ +/* */ +/* ERC_System_Error System error handing function*/ +/* TCC_Create_HISR Create timer HISR */ +/* TCCE_Create_HISR Create timer HISR (error chk)*/ +/* */ +/* INPUTS */ +/* */ +/* (Indirect) */ +/* TMD_HISR_Stack_Ptr Pointer to HISR stack area */ +/* TMD_HISR_Stack_Size Size of HISR stack */ +/* TMD_HISR_Priority Priority of timer HISR */ +/* */ +/* OUTPUTS */ +/* */ +/* TMD_Created_Timers_List Pointer to the linked-list */ +/* of created application */ +/* timers */ +/* TMD_Total_Timers Total number of created */ +/* application timers */ +/* TMD_Active_Timers_List Pointer to the linked-list */ +/* of active timers. */ +/* TMD_Active_List_Busy Flag indicating that the */ +/* active timer list is in use*/ +/* TMD_Created_List_Protect Created timer list protect */ +/* structure */ +/* TMD_System_Clock System clock */ +/* TMD_Timer Timer count-down value */ +/* TMD_Timer_State State of timer */ +/* TMD_Time_Slice Time slice count-down value */ +/* TMD_Time_Slice_Task Pointer to task to time-slice*/ +/* TMD_Time_Slice_State State of time slice */ +/* TMD_HISR Timer HISR control block */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 08-09-1993 Removed timer task creation, */ +/* cleared the ID of the HISR */ +/* control block, and casted the */ +/* HISR priority, resulting in */ +/* version 1.0a */ +/* 08-09-1993 Verified version 1.0a */ +/* 03-01-1994 Modified HISR create function */ +/* interface, removed reference */ +/* to timer list protect since it */ +/* was deleted, resulting in */ +/* version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +VOID TMI_Initialize(VOID) +{ + +STATUS status; /* Return status of creates */ + + + /* Initialize the created application timer's list to NU_NULL. */ + TMD_Created_Timers_List = NU_NULL; + + /* Initialize the total number of created application timers to 0. */ + TMD_Total_Timers = 0; + + /* Initialize the active timer's list to NU_NULL. */ + TMD_Active_Timers_List = NU_NULL; + + /* Clear the active timer list busy flag. */ + TMD_Active_List_Busy = NU_FALSE; + + /* Initialize the system clock to 0. */ + TMD_System_Clock = 0; + + /* Initialize the timer to 0 and the timer state to "not active." */ + TMD_Timer = 0; + TMD_Timer_State = TM_NOT_ACTIVE; + + /* Initialize the time-slice timer, task pointer, and the associated + state variable. */ + TMD_Time_Slice = 0; + TMD_Time_Slice_Task = NU_NULL; + TMD_Time_Slice_State = TM_NOT_ACTIVE; + + /* Initialize the list protection structures. */ + TMD_Created_List_Protect.tc_tcb_pointer = NU_NULL; + + /* Clear out the timer HISR control block. */ + TMD_HISR.tc_id = 0; + + /* Create the timer HISR. The timer HISR is responsible for performing + the time slice function and activating the timer task if necessary. */ +#ifdef NU_NO_ERROR_CHECKING + + status = TCC_Create_HISR((NU_HISR *) &TMD_HISR, "SYSTEM H", + TMC_Timer_HISR, (OPTION) TMD_HISR_Priority, + TMD_HISR_Stack_Ptr, TMD_HISR_Stack_Size); +#else + + status = TCCE_Create_HISR((NU_HISR *) &TMD_HISR, "SYSTEM H", + TMC_Timer_HISR, (OPTION) TMD_HISR_Priority, + TMD_HISR_Stack_Ptr, TMD_HISR_Stack_Size); + +#endif + + /* Check for a system error creating the timer HISR. */ + if (status != NU_SUCCESS) + + /* Call the system error handler. */ + ERC_System_Error(NU_ERROR_CREATING_TIMER_HISR); +} + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/tms.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,630 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* tms.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* TM - Timer Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains supplemental routines for the timer */ +/* management component. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* TMS_Create_Timer Create an application timer */ +/* TMS_Delete_Timer Delete an application timer */ +/* TMS_Reset_Timer Reset application timer */ +/* TMS_Control_Timer Enable/Disable application */ +/* timer */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tc_extr.h Thread Control functions */ +/* tm_extr.h Timer functions */ +/* hi_extr.h History functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1994 Created initial version 1.1 from */ +/* previous version of TMC.C */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3. */ +/* 03-26-1999 Released 1.11m (new release */ +/* numbering scheme) */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tc_extr.h" /* Thread control functions */ +#include "tm_extr.h" /* Timer functions */ +#include "hi_extr.h" /* History functions */ +#include "profiler.h" /* ProView interface */ + + +/* Define external inner-component global data references. */ + +extern CS_NODE *TMD_Created_Timers_List; +extern UNSIGNED TMD_Total_Timers; +extern TM_TCB *TMD_Active_Timers_List; +extern INT TMD_Active_List_Busy; +extern TC_PROTECT TMD_Created_List_Protect; + + +/* Define internal function prototypes. */ + +VOID TMC_Start_Timer(TM_TCB *timer, UNSIGNED time); +VOID TMC_Stop_Timer(TM_TCB *timer); + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TMS_Create_Timer */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function creates an application timer and places it on the */ +/* list of created timers. The timer is activated if designated by */ +/* the enable parameter. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* TMSE_Create_Timer Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Place_On_List Add node to linked-list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Data structure protect */ +/* TCT_Unprotect Un-protect data structure */ +/* TMS_Control_Timer Enable the new timer */ +/* */ +/* INPUTS */ +/* */ +/* timer_ptr Timer control block pointer */ +/* name Timer name */ +/* expiration_routine Timer expiration routine */ +/* id Timer expiration ID */ +/* initial_time Initial expiration time */ +/* reschedule_time Reschedule expiration time */ +/* enable Automatic enable option */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function prototype, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TMS_Create_Timer(NU_TIMER *timer_ptr, CHAR *name, + VOID (*expiration_routine)(UNSIGNED), UNSIGNED id, + UNSIGNED initial_time, UNSIGNED reschedule_time, OPTION enable) +{ + +R1 TM_APP_TCB *timer; /* Timer control block ptr */ +INT i; /* Working index variable */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input timer pointer into internal pointer. */ + timer = (TM_APP_TCB *) timer_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_CREATE_TIMER_ID, (UNSIGNED) timer, + (UNSIGNED) name, (UNSIGNED) expiration_routine); + +#endif + + /* First, clear the timer ID just in case it is an old Timer + Control Block. */ + timer -> tm_id = 0; + + /* Fill in the timer name. */ + for (i = 0; i < NU_MAX_NAME; i++) + timer -> tm_name[i] = name[i]; + + /* Load the timer with the appropriate values. */ + timer -> tm_expiration_routine = expiration_routine; + timer -> tm_expiration_id = id; + timer -> tm_expirations = 0; + timer -> tm_initial_time = initial_time; + timer -> tm_reschedule_time = reschedule_time; + timer -> tm_actual_timer.tm_timer_type = TM_APPL_TIMER; + timer -> tm_enabled = NU_FALSE; + + /* Initialize link pointers. */ + timer -> tm_created.cs_previous = NU_NULL; + timer -> tm_created.cs_next = NU_NULL; + timer -> tm_actual_timer.tm_next_timer = NU_NULL; + timer -> tm_actual_timer.tm_previous_timer= NU_NULL; + timer -> tm_actual_timer.tm_information = (VOID *) timer; + + /* Protect against access to the list of created timers. */ + TCT_Protect(&TMD_Created_List_Protect); + + /* At this point the timer is completely built. The ID can now be + set and it can be linked into the created timer list. */ + timer -> tm_id = TM_TIMER_ID; + + /* Link the timer into the list of created timers and increment the + total number of timers in the system. */ + CSC_Place_On_List(&TMD_Created_Timers_List, &(timer -> tm_created)); + TMD_Total_Timers++; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTimer(RT_PROF_CREATE_TIMER,timer,RT_PROF_OK); +#endif + + /* Release protection against access to the list of created timers. */ + TCT_Unprotect(); + + /* Determine if the timer should be enabled. */ + if (enable == NU_ENABLE_TIMER) + + /* Activate the timer. */ + TMS_Control_Timer(timer_ptr, NU_ENABLE_TIMER); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return successful completion. */ + return(NU_SUCCESS); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TMS_Delete_Timer */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function deletes an application timer and removes it from */ +/* the list of created timers. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* TMSE_Delete_Timer Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* CSC_Remove_From_List Remove node from list */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_Protect Protect created list */ +/* TCT_System_Protect Protect active list */ +/* TCT_Unprotect Release protection */ +/* */ +/* INPUTS */ +/* */ +/* timer_ptr Timer control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_NOT_DISABLED Timer not disabled first */ +/* NU_SUCCESS */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified protection logic to use */ +/* system protection, changed */ +/* function prototype, resulting */ +/* in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TMS_Delete_Timer(NU_TIMER *timer_ptr) +{ + +TM_APP_TCB *timer; /* Timer control block ptr */ +STATUS status; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input timer pointer into internal pointer. */ + timer = (TM_APP_TCB *) timer_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_DELETE_TIMER_ID, (UNSIGNED) timer, + (UNSIGNED) 0, (UNSIGNED) 0); + +#endif + + /* Initialize the status. */ + status = NU_SUCCESS; + + /* Use system protect to protect the active timer list temporarily. */ + TCT_System_Protect(); + + /* Determine if the timer is currently disabled. */ + if (timer -> tm_enabled) + { + /* Error, indicate to the caller that the timer is currently active. */ + status = NU_NOT_DISABLED; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTimer(RT_PROF_DELETE_TIMER,timer,RT_PROF_FAIL); +#endif + + } + else + { + /* Clear the timer ID. */ + timer -> tm_id = 0; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTimer(RT_PROF_DELETE_TIMER,timer,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + + } + + /* Release protection. */ + TCT_Unprotect(); + + /* Determine if an error was detected. */ + if (status == NU_SUCCESS) + { + + /* Protect against access to the list of created timers. */ + TCT_Protect(&TMD_Created_List_Protect); + + /* Remove the timer from the list of created timers. */ + CSC_Remove_From_List(&TMD_Created_Timers_List, &(timer -> tm_created)); + + /* Decrement the total number of created timers. */ + TMD_Total_Timers--; + + /* Release protection against access to the list of created timers. */ + TCT_Unprotect(); + } + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TMS_Reset_Timer */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function resets the specified application timer. Note that */ +/* the timer must be in a disabled state prior to this call. The */ +/* timer is activated after it is reset if the enable parameter */ +/* specifies automatic activation. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* TMSE_Reset_Timer Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_System_Protect Protect active list */ +/* TCT_Unprotect Release protection */ +/* TMS_Control_Timer Enable/disable timer */ +/* */ +/* INPUTS */ +/* */ +/* timer_ptr Timer control block pointer */ +/* expiration_routine Timer expiration routine */ +/* initial_time Initial expiration time */ +/* reschedule_time Reschedule expiration time */ +/* enable Automatic enable option */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_NOT_DISABLED Timer not disabled first */ +/* NU_SUCCESS Successful completion */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified protection logic to use */ +/* system protection, changed */ +/* function prototype, resulting */ +/* in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TMS_Reset_Timer(NU_TIMER *timer_ptr, + VOID (*expiration_routine)(UNSIGNED), + UNSIGNED initial_time, UNSIGNED reschedule_time, OPTION enable) +{ + +R1 TM_APP_TCB *timer; /* Timer control block ptr */ +STATUS status; /* Completion status */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input timer pointer into internal pointer. */ + timer = (TM_APP_TCB *) timer_ptr; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_RESET_TIMER_ID, (UNSIGNED) timer, + (UNSIGNED) expiration_routine, (UNSIGNED) initial_time); + +#endif + + /* Protect against access to the active timer list. */ + TCT_System_Protect(); + + /* Determine if this timer is active. An active timer cannot be + reset. */ + if (timer -> tm_enabled) + { + + /* Indicate that the timer is active by returning the proper status. */ + status = NU_NOT_DISABLED; + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTimer(RT_PROF_RESET_TIMER,timer,RT_PROF_FAIL); +#endif /* INCLUDE_PROVIEW */ + + } + else + { + + /* Load the timer with the appropriate values. */ + timer -> tm_expiration_routine = expiration_routine; + timer -> tm_expirations = 0; + timer -> tm_initial_time = initial_time; + timer -> tm_reschedule_time = reschedule_time; + + /* Indicate successful completion status. */ + status = NU_SUCCESS; +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTimer(RT_PROF_RESET_TIMER,timer,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + + } + + /* Release protection. */ + TCT_Unprotect(); + + /* Determine if the timer needs to be enabled. */ + if ((status == NU_SUCCESS) && (enable == NU_ENABLE_TIMER)) + + /* Activate the timer. */ + TMS_Control_Timer(timer_ptr, NU_ENABLE_TIMER); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TMS_Control_Timer */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function either enables or disables the specified timer. */ +/* If the timer is already in the desired state, simply leave it */ +/* alone. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* TMSE_Control_Timer Error checking shell */ +/* */ +/* CALLS */ +/* */ +/* [HIC_Make_History_Entry] Make entry in history log */ +/* [TCT_Check_Stack] Stack checking function */ +/* TCT_System_Protect Protect the active list */ +/* TCT_Unprotect Release protection */ +/* TMC_Start_Timer Start a timer */ +/* TMC_Stop_Timer Stop a timer */ +/* */ +/* INPUTS */ +/* */ +/* app_timer Timer control block pointer */ +/* enable Disable/enable timer option */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_SUCCESS If service is successful */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Modified protection logic to use */ +/* system protection, changed */ +/* function prototype, resulting */ +/* in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TMS_Control_Timer(NU_TIMER *app_timer, OPTION enable) +{ + +R1 TM_APP_TCB *timer; /* Timer control block ptr */ +TM_TCB *timer_ptr; /* Actual timer pointer */ +UNSIGNED time; /* Variable to hold request */ +NU_SUPERV_USER_VARIABLES + + /* Switch to supervisor mode */ + NU_SUPERVISOR_MODE(); + + /* Move input timer pointer into internal pointer. */ + timer = (TM_APP_TCB *) app_timer; + + +#ifdef NU_ENABLE_STACK_CHECK + + /* Call stack checking function to check for an overflow condition. */ + TCT_Check_Stack(); + +#endif + +#ifdef NU_ENABLE_HISTORY + + /* Make an entry that corresponds to this function in the system history + log. */ + HIC_Make_History_Entry(NU_CONTROL_TIMER_ID, (UNSIGNED) timer, + (UNSIGNED) enable, (UNSIGNED) 0); + +#endif + + /* Protect against simultaneous access to the active timer list. */ + TCT_System_Protect(); + + /* Setup pointer to actual timer part of the control block. */ + timer_ptr = &(timer -> tm_actual_timer); + + /* Determine what type of request is present. */ + if ((enable == NU_ENABLE_TIMER) && (!timer -> tm_enabled)) + { + + /* Enable timer request is present and timer is currently disabled. */ + + /* Determine how to setup the remaining field in the actual timer. */ + if (timer -> tm_expirations) + + /* Use reschedule time since this timer has expired previously. */ + time = timer -> tm_reschedule_time; + else + + /* Use initial time since this timer has never expired. */ + time = timer -> tm_initial_time; + + /* Mark the application timer as enabled. */ + timer -> tm_enabled = NU_TRUE; + + /* Call the start timer routine to actually start the timer. */ + TMC_Start_Timer(&(timer -> tm_actual_timer), time); + } + else if ((enable == NU_DISABLE_TIMER) && (timer -> tm_enabled)) + { + + /* Disable timer request is present and timer is currently enabled. */ + TMC_Stop_Timer(timer_ptr); + + /* Mark the timer as disabled. */ + timer -> tm_enabled = NU_FALSE; + } + +#ifdef INCLUDE_PROVIEW + _RTProf_DumpTimer(RT_PROF_CONTROL_TIMER,timer,RT_PROF_OK); +#endif /* INCLUDE_PROVIEW */ + /* Release protection. */ + TCT_Unprotect(); + + /* Return to user mode */ + NU_USER_MODE(); + + /* Return the completion status. */ + return(NU_SUCCESS); +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nucleus/tmse.c Sun Jul 15 20:57:33 2018 +0000 @@ -0,0 +1,414 @@ +/*************************************************************************/ +/* */ +/* Copyright Mentor Graphics Corporation 2002 */ +/* All Rights Reserved. */ +/* */ +/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ +/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ +/* SUBJECT TO LICENSE TERMS. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* FILE NAME VERSION */ +/* */ +/* tmse.c Nucleus PLUS 1.14 */ +/* */ +/* COMPONENT */ +/* */ +/* TM - Timer Management */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains the error checking routines for the functions */ +/* in the Timer component. This permits easy removal of error */ +/* checking logic when it is not needed. */ +/* */ +/* DATA STRUCTURES */ +/* */ +/* None */ +/* */ +/* FUNCTIONS */ +/* */ +/* TMSE_Create_Timer Create an application timer */ +/* TMSE_Delete_Timer Delete an application timer */ +/* TMSE_Reset_Timer Reset application timer */ +/* TMSE_Control_Timer Enable/Disable application */ +/* timer */ +/* */ +/* DEPENDENCIES */ +/* */ +/* cs_extr.h Common Service functions */ +/* tm_extr.h Timer functions */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed names of error checking */ +/* shell to match new conventions, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* 04-17-1996 updated to version 1.2 */ +/* 03-24-1998 Released version 1.3 */ +/* 04-17-2002 Released version 1.13m */ +/* 11-07-2002 Released version 1.14 */ +/*************************************************************************/ +#define NU_SOURCE_FILE + + +#include "cs_extr.h" /* Common service functions */ +#include "tm_extr.h" /* Timer functions */ + + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TMSE_Create_Timer */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the create timer function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TMS_Create_Timer Actual create timer function */ +/* */ +/* INPUTS */ +/* */ +/* timer_ptr Timer control block pointer */ +/* name Timer name */ +/* expiration_routine Timer expiration routine */ +/* id Timer expiration ID */ +/* initial_time Initial expiration time */ +/* reschedule_time Reschedule expiration time */ +/* enable Automatic enable option */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_TIMER Indicates timer pointer is */ +/* NULL */ +/* NU_INVALID_FUNCTION Indicates timer expiration */ +/* function pointer is NULL */ +/* NU_INVALID_ENABLE Indicates enable parameter */ +/* is invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TMSE_Create_Timer(NU_TIMER *timer_ptr, CHAR *name, + VOID (*expiration_routine)(UNSIGNED), UNSIGNED id, + UNSIGNED initial_time, UNSIGNED reschedule_time, OPTION enable) +{ + +TM_APP_TCB *timer; /* Timer control block ptr */ +STATUS status; /* Completion status */ + + + /* Move input timer pointer into internal pointer. */ + timer = (TM_APP_TCB *) timer_ptr; + + /* Check the parameters to the create timer function. */ + if ((timer == NU_NULL) || (timer -> tm_id == TM_TIMER_ID)) + + /* Invalid timer pointer. */ + status = NU_INVALID_TIMER; + + else if (expiration_routine == NU_NULL) + + /* Invalid expiration function pointer. */ + status = NU_INVALID_FUNCTION; + + else if (initial_time == 0) + + /* Invalid time value. */ + status = NU_INVALID_OPERATION; + + + else if ((enable != NU_ENABLE_TIMER) && (enable != NU_DISABLE_TIMER)) + + /* Invalid enable parameter. */ + status = NU_INVALID_ENABLE; + + else + + /* Call the actual create timer function. */ + status = TMS_Create_Timer(timer_ptr, name, expiration_routine, id, + initial_time, reschedule_time, enable); + + /* Return the completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TMSE_Delete_Timer */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the delete timer function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TMS_Delete_Timer Actual delete timer function */ +/* */ +/* INPUTS */ +/* */ +/* timer_ptr Timer control block pointer */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_TIMER Indicates the timer pointer */ +/* is NULL or not a timer */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TMSE_Delete_Timer(NU_TIMER *timer_ptr) +{ + +TM_APP_TCB *timer; /* Timer control block ptr */ +STATUS status; /* Completion status */ + + + /* Move input timer pointer into internal pointer. */ + timer = (TM_APP_TCB *) timer_ptr; + + /* Check the parameters to the delete timer function. */ + if (timer == NU_NULL) + + /* Invalid timer pointer. */ + status = NU_INVALID_TIMER; + + else if (timer -> tm_id != TM_TIMER_ID) + + /* Invalid timer pointer. */ + status = NU_INVALID_TIMER; + + else + + /* Call the actual delete timer function. */ + status = TMS_Delete_Timer(timer_ptr); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TMSE_Reset_Timer */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the reset timer function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TMS_Reset_Timer Actual reset timer function */ +/* */ +/* INPUTS */ +/* */ +/* timer_ptr Timer control block pointer */ +/* expiration_routine Timer expiration routine */ +/* initial_time Initial expiration time */ +/* reschedule_time Reschedule expiration time */ +/* enable Automatic enable option */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_TIMER Indicates timer pointer is */ +/* invalid */ +/* NU_INVALID_FUNCTION Indicates that expiration */ +/* function pointer is NULL */ +/* NU_INVALID_ENABLE Indicates enable parameter */ +/* is invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TMSE_Reset_Timer(NU_TIMER *timer_ptr, + VOID (*expiration_routine)(UNSIGNED), + UNSIGNED initial_time, UNSIGNED reschedule_time, OPTION enable) +{ + +TM_APP_TCB *timer; /* Timer contorl block ptr */ +STATUS status; /* Completion status */ + + + /* Move input timer pointer into internal pointer. */ + timer = (TM_APP_TCB *) timer_ptr; + + /* Check the parameters to the reset timer function. */ + if (timer == NU_NULL) + + /* Invalid timer pointer. */ + status = NU_INVALID_TIMER; + + else if (timer -> tm_id != TM_TIMER_ID) + + /* Invalid timer pointer. */ + status = NU_INVALID_TIMER; + + else if (initial_time == 0) + + /* Invalid time value. */ + status = NU_INVALID_OPERATION; + + + else if (expiration_routine == NU_NULL) + + /* Invalid expiration function pointer. */ + status = NU_INVALID_FUNCTION; + + else if ((enable != NU_ENABLE_TIMER) && (enable != NU_DISABLE_TIMER)) + + /* Invalid enable parameter. */ + status = NU_INVALID_ENABLE; + + else + + /* Call the actual reset timer function. */ + status = TMS_Reset_Timer(timer_ptr, expiration_routine, initial_time, + reschedule_time, enable); + + /* Return completion status. */ + return(status); +} + + +/*************************************************************************/ +/* */ +/* FUNCTION */ +/* */ +/* TMSE_Control_Timer */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs error checking on the parameters supplied */ +/* to the control timer function. */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* CALLS */ +/* */ +/* TMS_Control_Timer Actual control timer function*/ +/* */ +/* INPUTS */ +/* */ +/* timer_ptr Timer control block pointer */ +/* enable Disable/enable timer option */ +/* */ +/* OUTPUTS */ +/* */ +/* NU_INVALID_TIMER Indicates the timer pointer */ +/* is invalid */ +/* NU_INVALID_ENABLE Indicates enable parameter */ +/* is invalid */ +/* */ +/* HISTORY */ +/* */ +/* DATE REMARKS */ +/* */ +/* 03-01-1993 Created initial version 1.0 */ +/* 04-19-1993 Verified version 1.0 */ +/* 03-01-1994 Changed function interface, */ +/* resulting in version 1.1 */ +/* */ +/* 03-18-1994 Verified version 1.1 */ +/* */ +/*************************************************************************/ +STATUS TMSE_Control_Timer(NU_TIMER *timer_ptr, OPTION enable) +{ + +TM_APP_TCB *timer; /* Timer control block ptr */ +STATUS status; /* Completion status */ + + + /* Move input timer pointer to internal pointer. */ + timer = (TM_APP_TCB *) timer_ptr; + + /* Check the parameters to the reset timer function. */ + if (timer == NU_NULL) + + /* Invalid timer pointer. */ + status = NU_INVALID_TIMER; + + else if (timer -> tm_id != TM_TIMER_ID) + + /* Invalid timer pointer. */ + status = NU_INVALID_TIMER; + + else if ((enable != NU_ENABLE_TIMER) && (enable != NU_DISABLE_TIMER)) + + /* Invalid enable parameter. */ + status = NU_INVALID_ENABLE; + + else + + /* Call actual control timer function. */ + status = TMS_Control_Timer(timer_ptr, enable); + + /* Return completion status. */ + return(status); +} + + + + +