mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-21 04:14:26 +08:00
Patch from Chris John <cjohns@awa.com.au> to add use of a select statement
in the unix port idle thread task. This should keep the entire application from blocking when any component does a blocking application. Also added TOD_MICROSECONDS_TO_TICKS.
This commit is contained in:
@@ -33,7 +33,7 @@ include $(PROJECT_ROOT)/make/leaf.cfg
|
|||||||
|
|
||||||
DEFINES +=
|
DEFINES +=
|
||||||
CPPFLAGS +=
|
CPPFLAGS +=
|
||||||
CFLAGS += $(CFLAGS_OS_V)
|
CFLAGS += $(CFLAGS_OS_V) -DCPU_SYNC_IO
|
||||||
|
|
||||||
LD_PATHS +=
|
LD_PATHS +=
|
||||||
LD_LIBS +=
|
LD_LIBS +=
|
||||||
|
|||||||
@@ -62,6 +62,18 @@ static Context_Control_overlay
|
|||||||
static Context_Control_overlay
|
static Context_Control_overlay
|
||||||
_CPU_Context_Default_with_ISRs_disabled CPU_STRUCTURE_ALIGNMENT;
|
_CPU_Context_Default_with_ISRs_disabled CPU_STRUCTURE_ALIGNMENT;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync IO support, an entry for each fd that can be set
|
||||||
|
*/
|
||||||
|
|
||||||
|
void _CPU_Sync_io_Init();
|
||||||
|
|
||||||
|
static rtems_sync_io_handler _CPU_Sync_io_handlers[FD_SETSIZE];
|
||||||
|
static int sync_io_nfds;
|
||||||
|
static fd_set sync_io_readfds;
|
||||||
|
static fd_set sync_io_writefds;
|
||||||
|
static fd_set sync_io_exceptfds;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Which cpu are we? Used by libcpu and libbsp.
|
* Which cpu are we? Used by libcpu and libbsp.
|
||||||
*/
|
*/
|
||||||
@@ -214,6 +226,24 @@ void _CPU_Context_From_CPU_Init()
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _CPU_Sync_io_Init
|
||||||
|
*/
|
||||||
|
|
||||||
|
void _CPU_Sync_io_Init()
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
for (fd = 0; fd < FD_SETSIZE; fd++)
|
||||||
|
_CPU_Sync_io_handlers[fd] = NULL;
|
||||||
|
|
||||||
|
sync_io_nfds = 0;
|
||||||
|
FD_ZERO(&sync_io_readfds);
|
||||||
|
FD_ZERO(&sync_io_writefds);
|
||||||
|
FD_ZERO(&sync_io_exceptfds);
|
||||||
|
}
|
||||||
|
|
||||||
/*PAGE
|
/*PAGE
|
||||||
*
|
*
|
||||||
* _CPU_ISR_Get_level
|
* _CPU_ISR_Get_level
|
||||||
@@ -272,6 +302,8 @@ void _CPU_Initialize(
|
|||||||
|
|
||||||
_CPU_ISR_From_CPU_Init();
|
_CPU_ISR_From_CPU_Init();
|
||||||
|
|
||||||
|
_CPU_Sync_io_Init();
|
||||||
|
|
||||||
_CPU_Context_From_CPU_Init();
|
_CPU_Context_From_CPU_Init();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -350,13 +382,52 @@ void _CPU_Install_interrupt_stack( void )
|
|||||||
|
|
||||||
void _CPU_Thread_Idle_body( void )
|
void _CPU_Thread_Idle_body( void )
|
||||||
{
|
{
|
||||||
|
#if CPU_SYNC_IO
|
||||||
|
extern void _Thread_Dispatch(void);
|
||||||
|
int fd;
|
||||||
|
#endif
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
#ifdef RTEMS_DEBUG
|
#ifdef RTEMS_DEBUG
|
||||||
/* interrupts had better be enabled at this point! */
|
/* interrupts had better be enabled at this point! */
|
||||||
if (_CPU_ISR_Get_level() != 0)
|
if (_CPU_ISR_Get_level() != 0)
|
||||||
abort();
|
abort();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Block on a select statement, the CPU interface added allow the
|
||||||
|
* user to add new descriptors which are to be blocked on
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if CPU_SYNC_IO
|
||||||
|
if (sync_io_nfds) {
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = select(sync_io_nfds,
|
||||||
|
&sync_io_readfds,
|
||||||
|
&sync_io_writefds,
|
||||||
|
&sync_io_exceptfds,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if ((result < 0) && (errno != EINTR))
|
||||||
|
_CPU_Fatal_error(0x200); /* FIXME : what number should go here !! */
|
||||||
|
|
||||||
|
for (fd = 0; fd < sync_io_nfds; fd++) {
|
||||||
|
boolean read = FD_ISSET(fd, &sync_io_readfds);
|
||||||
|
boolean write = FD_ISSET(fd, &sync_io_writefds);
|
||||||
|
boolean except = FD_ISSET(fd, &sync_io_exceptfds);
|
||||||
|
|
||||||
|
if (_CPU_Sync_io_handlers[fd] && (read || write || except))
|
||||||
|
_CPU_Sync_io_handlers[fd](fd, read, write, except);
|
||||||
|
|
||||||
|
_Thread_Dispatch();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
pause();
|
||||||
|
#else
|
||||||
pause();
|
pause();
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -756,6 +827,55 @@ void _CPU_Fatal_error(unsigned32 error)
|
|||||||
* Special Purpose Routines to hide the use of UNIX system calls.
|
* Special Purpose Routines to hide the use of UNIX system calls.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
int _CPU_Set_sync_io_handler(
|
||||||
|
int fd,
|
||||||
|
boolean read,
|
||||||
|
boolean write,
|
||||||
|
boolean except,
|
||||||
|
rtems_sync_io_handler handler
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ((fd < FD_SETSIZE) && (_CPU_Sync_io_handlers[fd] == NULL)) {
|
||||||
|
if (read)
|
||||||
|
FD_SET(fd, &sync_io_readfds);
|
||||||
|
else
|
||||||
|
FD_CLR(fd, &sync_io_readfds);
|
||||||
|
if (write)
|
||||||
|
FD_SET(fd, &sync_io_writefds);
|
||||||
|
else
|
||||||
|
FD_CLR(fd, &sync_io_writefds);
|
||||||
|
if (except)
|
||||||
|
FD_SET(fd, &sync_io_exceptfds);
|
||||||
|
else
|
||||||
|
FD_CLR(fd, &sync_io_exceptfds);
|
||||||
|
_CPU_Sync_io_handlers[fd] = handler;
|
||||||
|
if ((fd + 1) > sync_io_nfds)
|
||||||
|
sync_io_nfds = fd + 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _CPU_Clear_sync_io_handler(
|
||||||
|
int fd
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ((fd < FD_SETSIZE) && _CPU_Sync_io_handlers[fd]) {
|
||||||
|
FD_CLR(fd, &sync_io_readfds);
|
||||||
|
FD_CLR(fd, &sync_io_writefds);
|
||||||
|
FD_CLR(fd, &sync_io_exceptfds);
|
||||||
|
_CPU_Sync_io_handlers[fd] = NULL;
|
||||||
|
sync_io_nfds = 0;
|
||||||
|
for (fd = 0; fd < FD_SETSIZE; fd++)
|
||||||
|
if (FD_ISSET(fd, &sync_io_readfds) ||
|
||||||
|
FD_ISSET(fd, &sync_io_writefds) ||
|
||||||
|
FD_ISSET(fd, &sync_io_exceptfds))
|
||||||
|
sync_io_nfds = fd;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int _CPU_Get_clock_vector( void )
|
int _CPU_Get_clock_vector( void )
|
||||||
{
|
{
|
||||||
return SIGALRM;
|
return SIGALRM;
|
||||||
@@ -934,14 +1054,15 @@ void _CPU_SHM_Lock(
|
|||||||
int semaphore
|
int semaphore
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
struct sembuf sb;
|
struct sembuf sb;
|
||||||
int status;
|
|
||||||
|
|
||||||
sb.sem_num = semaphore;
|
sb.sem_num = semaphore;
|
||||||
sb.sem_op = -1;
|
sb.sem_op = -1;
|
||||||
sb.sem_flg = 0;
|
sb.sem_flg = 0;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
int status = -1;
|
||||||
|
|
||||||
status = semop(_CPU_SHM_Semid, &sb, 1);
|
status = semop(_CPU_SHM_Semid, &sb, 1);
|
||||||
if ( status >= 0 )
|
if ( status >= 0 )
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -995,6 +995,32 @@ static inline unsigned int CPU_swap_u32(
|
|||||||
* Special Purpose Routines to hide the use of UNIX system calls.
|
* Special Purpose Routines to hide the use of UNIX system calls.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pointer to a sync io Handler
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef void ( *rtems_sync_io_handler )(
|
||||||
|
int fd,
|
||||||
|
boolean read,
|
||||||
|
boolean wrtie,
|
||||||
|
boolean except
|
||||||
|
);
|
||||||
|
|
||||||
|
/* returns -1 if fd to large, 0 is successful */
|
||||||
|
int _CPU_Set_sync_io_handler(
|
||||||
|
int fd,
|
||||||
|
boolean read,
|
||||||
|
boolean write,
|
||||||
|
boolean except,
|
||||||
|
rtems_sync_io_handler handler
|
||||||
|
);
|
||||||
|
|
||||||
|
/* returns -1 if fd to large, o if successful */
|
||||||
|
int _CPU_Clear_sync_io_handler(
|
||||||
|
int fd
|
||||||
|
);
|
||||||
|
|
||||||
int _CPU_Get_clock_vector( void );
|
int _CPU_Get_clock_vector( void );
|
||||||
|
|
||||||
void _CPU_Start_clock(
|
void _CPU_Start_clock(
|
||||||
|
|||||||
@@ -235,6 +235,21 @@ void _TOD_Tickle(
|
|||||||
|
|
||||||
#define TOD_MILLISECONDS_TO_MICROSECONDS(_ms) ((_ms) * 1000)
|
#define TOD_MILLISECONDS_TO_MICROSECONDS(_ms) ((_ms) * 1000)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TOD_MICROSECONDS_TO_TICKS
|
||||||
|
*
|
||||||
|
* DESCRIPTION:
|
||||||
|
*
|
||||||
|
* This routine converts an interval expressed in microseconds to ticks.
|
||||||
|
*
|
||||||
|
* NOTE:
|
||||||
|
*
|
||||||
|
* This must be a macro so it can be used in "static" tables.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define TOD_MICROSECONDS_TO_TICKS(_us) \
|
||||||
|
((_us) / _TOD_Microseconds_per_tick)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TOD_MILLISECONDS_TO_TICKS
|
* TOD_MILLISECONDS_TO_TICKS
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -235,6 +235,21 @@ void _TOD_Tickle(
|
|||||||
|
|
||||||
#define TOD_MILLISECONDS_TO_MICROSECONDS(_ms) ((_ms) * 1000)
|
#define TOD_MILLISECONDS_TO_MICROSECONDS(_ms) ((_ms) * 1000)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TOD_MICROSECONDS_TO_TICKS
|
||||||
|
*
|
||||||
|
* DESCRIPTION:
|
||||||
|
*
|
||||||
|
* This routine converts an interval expressed in microseconds to ticks.
|
||||||
|
*
|
||||||
|
* NOTE:
|
||||||
|
*
|
||||||
|
* This must be a macro so it can be used in "static" tables.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define TOD_MICROSECONDS_TO_TICKS(_us) \
|
||||||
|
((_us) / _TOD_Microseconds_per_tick)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TOD_MILLISECONDS_TO_TICKS
|
* TOD_MILLISECONDS_TO_TICKS
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -62,6 +62,18 @@ static Context_Control_overlay
|
|||||||
static Context_Control_overlay
|
static Context_Control_overlay
|
||||||
_CPU_Context_Default_with_ISRs_disabled CPU_STRUCTURE_ALIGNMENT;
|
_CPU_Context_Default_with_ISRs_disabled CPU_STRUCTURE_ALIGNMENT;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync IO support, an entry for each fd that can be set
|
||||||
|
*/
|
||||||
|
|
||||||
|
void _CPU_Sync_io_Init();
|
||||||
|
|
||||||
|
static rtems_sync_io_handler _CPU_Sync_io_handlers[FD_SETSIZE];
|
||||||
|
static int sync_io_nfds;
|
||||||
|
static fd_set sync_io_readfds;
|
||||||
|
static fd_set sync_io_writefds;
|
||||||
|
static fd_set sync_io_exceptfds;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Which cpu are we? Used by libcpu and libbsp.
|
* Which cpu are we? Used by libcpu and libbsp.
|
||||||
*/
|
*/
|
||||||
@@ -214,6 +226,24 @@ void _CPU_Context_From_CPU_Init()
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _CPU_Sync_io_Init
|
||||||
|
*/
|
||||||
|
|
||||||
|
void _CPU_Sync_io_Init()
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
for (fd = 0; fd < FD_SETSIZE; fd++)
|
||||||
|
_CPU_Sync_io_handlers[fd] = NULL;
|
||||||
|
|
||||||
|
sync_io_nfds = 0;
|
||||||
|
FD_ZERO(&sync_io_readfds);
|
||||||
|
FD_ZERO(&sync_io_writefds);
|
||||||
|
FD_ZERO(&sync_io_exceptfds);
|
||||||
|
}
|
||||||
|
|
||||||
/*PAGE
|
/*PAGE
|
||||||
*
|
*
|
||||||
* _CPU_ISR_Get_level
|
* _CPU_ISR_Get_level
|
||||||
@@ -272,6 +302,8 @@ void _CPU_Initialize(
|
|||||||
|
|
||||||
_CPU_ISR_From_CPU_Init();
|
_CPU_ISR_From_CPU_Init();
|
||||||
|
|
||||||
|
_CPU_Sync_io_Init();
|
||||||
|
|
||||||
_CPU_Context_From_CPU_Init();
|
_CPU_Context_From_CPU_Init();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -350,13 +382,52 @@ void _CPU_Install_interrupt_stack( void )
|
|||||||
|
|
||||||
void _CPU_Thread_Idle_body( void )
|
void _CPU_Thread_Idle_body( void )
|
||||||
{
|
{
|
||||||
|
#if CPU_SYNC_IO
|
||||||
|
extern void _Thread_Dispatch(void);
|
||||||
|
int fd;
|
||||||
|
#endif
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
#ifdef RTEMS_DEBUG
|
#ifdef RTEMS_DEBUG
|
||||||
/* interrupts had better be enabled at this point! */
|
/* interrupts had better be enabled at this point! */
|
||||||
if (_CPU_ISR_Get_level() != 0)
|
if (_CPU_ISR_Get_level() != 0)
|
||||||
abort();
|
abort();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Block on a select statement, the CPU interface added allow the
|
||||||
|
* user to add new descriptors which are to be blocked on
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if CPU_SYNC_IO
|
||||||
|
if (sync_io_nfds) {
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = select(sync_io_nfds,
|
||||||
|
&sync_io_readfds,
|
||||||
|
&sync_io_writefds,
|
||||||
|
&sync_io_exceptfds,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if ((result < 0) && (errno != EINTR))
|
||||||
|
_CPU_Fatal_error(0x200); /* FIXME : what number should go here !! */
|
||||||
|
|
||||||
|
for (fd = 0; fd < sync_io_nfds; fd++) {
|
||||||
|
boolean read = FD_ISSET(fd, &sync_io_readfds);
|
||||||
|
boolean write = FD_ISSET(fd, &sync_io_writefds);
|
||||||
|
boolean except = FD_ISSET(fd, &sync_io_exceptfds);
|
||||||
|
|
||||||
|
if (_CPU_Sync_io_handlers[fd] && (read || write || except))
|
||||||
|
_CPU_Sync_io_handlers[fd](fd, read, write, except);
|
||||||
|
|
||||||
|
_Thread_Dispatch();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
pause();
|
||||||
|
#else
|
||||||
pause();
|
pause();
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -756,6 +827,55 @@ void _CPU_Fatal_error(unsigned32 error)
|
|||||||
* Special Purpose Routines to hide the use of UNIX system calls.
|
* Special Purpose Routines to hide the use of UNIX system calls.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
int _CPU_Set_sync_io_handler(
|
||||||
|
int fd,
|
||||||
|
boolean read,
|
||||||
|
boolean write,
|
||||||
|
boolean except,
|
||||||
|
rtems_sync_io_handler handler
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ((fd < FD_SETSIZE) && (_CPU_Sync_io_handlers[fd] == NULL)) {
|
||||||
|
if (read)
|
||||||
|
FD_SET(fd, &sync_io_readfds);
|
||||||
|
else
|
||||||
|
FD_CLR(fd, &sync_io_readfds);
|
||||||
|
if (write)
|
||||||
|
FD_SET(fd, &sync_io_writefds);
|
||||||
|
else
|
||||||
|
FD_CLR(fd, &sync_io_writefds);
|
||||||
|
if (except)
|
||||||
|
FD_SET(fd, &sync_io_exceptfds);
|
||||||
|
else
|
||||||
|
FD_CLR(fd, &sync_io_exceptfds);
|
||||||
|
_CPU_Sync_io_handlers[fd] = handler;
|
||||||
|
if ((fd + 1) > sync_io_nfds)
|
||||||
|
sync_io_nfds = fd + 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _CPU_Clear_sync_io_handler(
|
||||||
|
int fd
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ((fd < FD_SETSIZE) && _CPU_Sync_io_handlers[fd]) {
|
||||||
|
FD_CLR(fd, &sync_io_readfds);
|
||||||
|
FD_CLR(fd, &sync_io_writefds);
|
||||||
|
FD_CLR(fd, &sync_io_exceptfds);
|
||||||
|
_CPU_Sync_io_handlers[fd] = NULL;
|
||||||
|
sync_io_nfds = 0;
|
||||||
|
for (fd = 0; fd < FD_SETSIZE; fd++)
|
||||||
|
if (FD_ISSET(fd, &sync_io_readfds) ||
|
||||||
|
FD_ISSET(fd, &sync_io_writefds) ||
|
||||||
|
FD_ISSET(fd, &sync_io_exceptfds))
|
||||||
|
sync_io_nfds = fd;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int _CPU_Get_clock_vector( void )
|
int _CPU_Get_clock_vector( void )
|
||||||
{
|
{
|
||||||
return SIGALRM;
|
return SIGALRM;
|
||||||
@@ -934,14 +1054,15 @@ void _CPU_SHM_Lock(
|
|||||||
int semaphore
|
int semaphore
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
struct sembuf sb;
|
struct sembuf sb;
|
||||||
int status;
|
|
||||||
|
|
||||||
sb.sem_num = semaphore;
|
sb.sem_num = semaphore;
|
||||||
sb.sem_op = -1;
|
sb.sem_op = -1;
|
||||||
sb.sem_flg = 0;
|
sb.sem_flg = 0;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
int status = -1;
|
||||||
|
|
||||||
status = semop(_CPU_SHM_Semid, &sb, 1);
|
status = semop(_CPU_SHM_Semid, &sb, 1);
|
||||||
if ( status >= 0 )
|
if ( status >= 0 )
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -235,6 +235,21 @@ void _TOD_Tickle(
|
|||||||
|
|
||||||
#define TOD_MILLISECONDS_TO_MICROSECONDS(_ms) ((_ms) * 1000)
|
#define TOD_MILLISECONDS_TO_MICROSECONDS(_ms) ((_ms) * 1000)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TOD_MICROSECONDS_TO_TICKS
|
||||||
|
*
|
||||||
|
* DESCRIPTION:
|
||||||
|
*
|
||||||
|
* This routine converts an interval expressed in microseconds to ticks.
|
||||||
|
*
|
||||||
|
* NOTE:
|
||||||
|
*
|
||||||
|
* This must be a macro so it can be used in "static" tables.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define TOD_MICROSECONDS_TO_TICKS(_us) \
|
||||||
|
((_us) / _TOD_Microseconds_per_tick)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TOD_MILLISECONDS_TO_TICKS
|
* TOD_MILLISECONDS_TO_TICKS
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user