forked from Imagelibrary/rtems
Initialization of semaphores was incorrect. It did not force
the count to "1" to indicate availability. Interrupt support was added. Problem where newlib's errno "overrides" that set by system calls was addressed. Fixed bug which resulted in all nodes using the same semaphore although an array of semaphores was allocated.
This commit is contained in:
@@ -11,17 +11,8 @@
|
||||
* OUTPUT PARAMETERS:
|
||||
* *shmcfg - pointer to SHM Config Table
|
||||
*
|
||||
* NOTES: The MP interrupt used is the Runway bus' ability to directly
|
||||
* address the control registers of up to four CPUs and cause
|
||||
* interrupts on them.
|
||||
*
|
||||
* The following table illustrates the configuration limitations:
|
||||
*
|
||||
* BUS MAX
|
||||
* MODE ENDIAN NODES
|
||||
* ========= ====== =======
|
||||
* POLLED BIG 2+
|
||||
* INTERRUPT BIG 2..4
|
||||
* NOTES: This driver is capable of supporting a practically unlimited
|
||||
* number of nodes.
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
@@ -43,13 +34,11 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/sem.h>
|
||||
|
||||
#define INTERRUPT 0 /* can be interrupt or polling */
|
||||
#define POLLING 1
|
||||
|
||||
shm_config_table BSP_shm_cfgtbl;
|
||||
|
||||
int semid;
|
||||
@@ -58,58 +47,103 @@ void Shm_Cause_interrupt_unix(
|
||||
rtems_unsigned32 node
|
||||
);
|
||||
|
||||
void Shm_Get_configuration(
|
||||
rtems_unsigned32 localnode,
|
||||
shm_config_table **shmcfg
|
||||
)
|
||||
void fix_semaphores( void )
|
||||
{
|
||||
rtems_unsigned32 maximum_nodes;
|
||||
int i;
|
||||
|
||||
int shmid;
|
||||
char *shm_addr;
|
||||
key_t shm_key;
|
||||
key_t sem_key;
|
||||
struct sembuf sb;
|
||||
int status;
|
||||
int shm_size;
|
||||
|
||||
shm_key = 0xa000;
|
||||
if (getenv("RTEMS_SHM_KEY"))
|
||||
shm_key = strtol(getenv("RTEMS_SHM_KEY"), 0, 0);
|
||||
else
|
||||
#ifdef RTEMS_SHM_KEY
|
||||
shm_key = RTEMS_SHM_KEY;
|
||||
#else
|
||||
shm_key = 0xa000;
|
||||
#endif
|
||||
|
||||
if (getenv("RTEMS_SHM_SIZE"))
|
||||
shm_size = strtol(getenv("RTEMS_SHM_SIZE"), 0, 0);
|
||||
else
|
||||
#ifdef RTEMS_SHM_SIZE
|
||||
shm_size = RTEMS_SHM_SIZE;
|
||||
#else
|
||||
shm_size = 64 * KILOBYTE;
|
||||
#endif
|
||||
|
||||
if (getenv("RTEMS_SHM_SEMAPHORE_KEY"))
|
||||
sem_key = strtol(getenv("RTEMS_SHM_SEMAPHORE_KEY"), 0, 0);
|
||||
else
|
||||
#ifdef RTEMS_SHM_SEMAPHORE_KEY
|
||||
sem_key = RTEMS_SHM_SEMAPHORE_KEY;
|
||||
#else
|
||||
sem_key = 0xa001;
|
||||
#endif
|
||||
|
||||
shmid = shmget(shm_key, 16 * KILOBYTE, IPC_CREAT | 0660);
|
||||
shmid = shmget(shm_key, shm_size, IPC_CREAT | 0660);
|
||||
if ( shmid == -1 ) {
|
||||
fix_syscall_errno(); /* in case of newlib */
|
||||
perror( "shmget" );
|
||||
exit( 0 );
|
||||
rtems_fatal_error_occurred(RTEMS_UNSATISFIED);
|
||||
}
|
||||
|
||||
shm_addr = shmat(shmid, (char *)0, SHM_RND);
|
||||
if ( shm_addr == (void *)-1 ) {
|
||||
fix_syscall_errno(); /* in case of newlib */
|
||||
perror( "shmat" );
|
||||
exit( 0 );
|
||||
rtems_fatal_error_occurred(RTEMS_UNSATISFIED);
|
||||
}
|
||||
|
||||
sem_key = 0xa001;
|
||||
|
||||
maximum_nodes = Shm_RTEMS_MP_Configuration->maximum_nodes;
|
||||
semid = semget(sem_key, maximum_nodes + 1, IPC_CREAT | 0660);
|
||||
if ( semid == -1 ) {
|
||||
fix_syscall_errno(); /* in case of newlib */
|
||||
perror( "semget" );
|
||||
exit( 0 );
|
||||
rtems_fatal_error_occurred(RTEMS_UNSATISFIED);
|
||||
}
|
||||
|
||||
if ( Shm_Is_master_node() ) {
|
||||
for ( i=0 ; i <= maximum_nodes ; i++ ) {
|
||||
sb.sem_op = 1;
|
||||
sb.sem_num = i;
|
||||
sb.sem_flg = 0;
|
||||
status = semop( semid, &sb, 1 );
|
||||
|
||||
#if defined(solaris2)
|
||||
union semun {
|
||||
int val;
|
||||
struct semid_ds *buf;
|
||||
ushort *array;
|
||||
} help;
|
||||
|
||||
help.val = 1;
|
||||
semctl( semid, i, SETVAL, help );
|
||||
#endif
|
||||
#if defined(hpux)
|
||||
semctl( semid, i, SETVAL, 1 );
|
||||
#endif
|
||||
|
||||
fix_syscall_errno(); /* in case of newlib */
|
||||
if ( status == -1 ) {
|
||||
fprintf( stderr, "Sem init failed %d\n", errno ); fflush( stderr );
|
||||
exit( 0 );
|
||||
rtems_fatal_error_occurred(RTEMS_UNSATISFIED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BSP_shm_cfgtbl.base = (vol_u32 *)shm_addr;
|
||||
BSP_shm_cfgtbl.length = 16 * KILOBYTE;
|
||||
BSP_shm_cfgtbl.length = shm_size;
|
||||
}
|
||||
|
||||
void Shm_Get_configuration(
|
||||
rtems_unsigned32 localnode,
|
||||
shm_config_table **shmcfg
|
||||
)
|
||||
{
|
||||
fix_semaphores();
|
||||
|
||||
BSP_shm_cfgtbl.format = SHM_BIG;
|
||||
|
||||
BSP_shm_cfgtbl.cause_intr = Shm_Cause_interrupt_unix;
|
||||
@@ -120,16 +154,16 @@ void Shm_Get_configuration(
|
||||
BSP_shm_cfgtbl.convert = CPU_swap_u32;
|
||||
#endif
|
||||
|
||||
#if ( POLLING == 1 )
|
||||
#ifdef INTERRUPT_EXTERNAL_MPCI
|
||||
BSP_shm_cfgtbl.poll_intr = INTR_MODE;
|
||||
BSP_shm_cfgtbl.Intr.address = (vol_u32 *) getpid(); /* process id */
|
||||
BSP_shm_cfgtbl.Intr.value = INTERRUPT_EXTERNAL_MPCI; /* signal to send */
|
||||
BSP_shm_cfgtbl.Intr.length = LONG;
|
||||
#else
|
||||
BSP_shm_cfgtbl.poll_intr = POLLED_MODE;
|
||||
BSP_shm_cfgtbl.Intr.address = NO_INTERRUPT;
|
||||
BSP_shm_cfgtbl.Intr.value = NO_INTERRUPT;
|
||||
BSP_shm_cfgtbl.Intr.length = NO_INTERRUPT;
|
||||
#else
|
||||
BSP_shm_cfgtbl.poll_intr = INTR_MODE;
|
||||
BSP_shm_cfgtbl.Intr.address = 0; /* process id? */
|
||||
BSP_shm_cfgtbl.Intr.value = 0; /* signal to send? */
|
||||
BSP_shm_cfgtbl.Intr.length = LONG;
|
||||
#endif
|
||||
|
||||
*shmcfg = &BSP_shm_cfgtbl;
|
||||
|
||||
@@ -23,9 +23,14 @@
|
||||
#include <shm.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
void Shm_Cause_interrupt_unix(
|
||||
rtems_unsigned32 node
|
||||
)
|
||||
{
|
||||
Shm_Interrupt_information *intr;
|
||||
intr = &Shm_Interrupt_table[node];
|
||||
|
||||
kill((pid_t) intr->address, intr->value);
|
||||
}
|
||||
|
||||
@@ -41,8 +41,7 @@ void Shm_Initialize_lock(
|
||||
Shm_Locked_queue_Control *lq_cb
|
||||
)
|
||||
{
|
||||
lq_cb->lock =
|
||||
( lq_cb - Shm_Locked_queues ) / sizeof( Shm_Locked_queue_Control );
|
||||
lq_cb->lock = lq_cb - Shm_Locked_queues;
|
||||
}
|
||||
|
||||
/* Shm_Lock( &lq_cb )
|
||||
@@ -60,24 +59,25 @@ void Shm_Lock(
|
||||
struct sembuf sb;
|
||||
int status;
|
||||
|
||||
isr_level = 0;
|
||||
|
||||
sb.sem_num = lq_cb->lock;
|
||||
sb.sem_op = -1;
|
||||
sb.sem_flg = 0;
|
||||
|
||||
rtems_interrupt_disable( isr_level );
|
||||
|
||||
Shm_isrstat = isr_level;
|
||||
|
||||
while (1) {
|
||||
status = semop(semid, &sb, 1);
|
||||
if ( status == 0 )
|
||||
if ( status >= 0 )
|
||||
break;
|
||||
if ( status == -1 && errno == EINTR )
|
||||
continue;
|
||||
|
||||
fprintf( stderr, "shm lock(%d %d)\n", status, errno );
|
||||
exit( 0 );
|
||||
if ( status == -1 ) {
|
||||
fix_syscall_errno(); /* in case of newlib */
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
perror("shm lock");
|
||||
rtems_fatal_error_occurred(RTEMS_UNSATISFIED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,21 +95,22 @@ void Shm_Unlock(
|
||||
struct sembuf sb;
|
||||
int status;
|
||||
|
||||
isr_level = 0;
|
||||
|
||||
sb.sem_num = lq_cb->lock;
|
||||
sb.sem_op = 1;
|
||||
sb.sem_flg = 0;
|
||||
|
||||
while (1) {
|
||||
status = semop(semid, &sb, 1);
|
||||
if ( status == 0 )
|
||||
if ( status >= 0 )
|
||||
break;
|
||||
if ( status == -1 && errno == EINTR )
|
||||
continue;
|
||||
|
||||
fprintf( stderr, "shm unlock(%d %d)\n", status, errno );
|
||||
exit( 0 );
|
||||
if ( status == -1 ) {
|
||||
fix_syscall_errno(); /* in case of newlib */
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
perror("shm unlock");
|
||||
rtems_fatal_error_occurred(RTEMS_UNSATISFIED);
|
||||
}
|
||||
}
|
||||
|
||||
isr_level = Shm_isrstat;
|
||||
|
||||
@@ -25,5 +25,7 @@
|
||||
|
||||
void Shm_setvec( void )
|
||||
{
|
||||
#ifdef INTERRUPT_EXTERNAL_MPCI
|
||||
set_vector( Shm_isr, INTERRUPT_EXTERNAL_MPCI, 1 );
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user