source: rtems/c/src/exec/score/cpu/unix/cpu.c @ 37f4c2d

4.104.114.84.95
Last change on this file since 37f4c2d was 37f4c2d, checked in by Joel Sherrill <joel.sherrill@…>, on 09/27/95 at 20:53:58

Modified UNIX simulator port so all references to native unix
stuff is in the executive source proper in the file cpu.c. This
should help avoid conflicts between RTEMS POSIX files and UNIX files.

  • Property mode set to 100644
File size: 19.8 KB
Line 
1/*
2 *  UNIX Simulator Dependent Source
3 *
4 *
5 *  To anyone who acknowledges that this file is provided "AS IS"
6 *  without any express or implied warranty:
7 *      permission to use, copy, modify, and distribute this file
8 *      for any purpose is hereby granted without fee, provided that
9 *      the above copyright notice and this notice appears in all
10 *      copies, and that the name of Division Incorporated not be
11 *      used in advertising or publicity pertaining to distribution
12 *      of the software without specific, written prior permission.
13 *      Division Incorporated makes no representations about the
14 *      suitability of this software for any purpose.
15 *
16 *  $Id$
17 */
18
19#include <rtems/system.h>
20#include <rtems/score/isr.h>
21#include <rtems/score/interr.h>
22
23#if defined(solaris2)
24#undef  _POSIX_C_SOURCE
25#define _POSIX_C_SOURCE 3
26#undef  __STRICT_ANSI__
27#define __STRICT_ANSI__
28#endif
29 
30#if defined(linux)
31#define MALLOC_0_RETURNS_NULL
32#endif
33 
34#include <stdio.h>
35#include <stdlib.h>
36#include <setjmp.h>
37#include <signal.h>
38#include <time.h>
39#include <sys/time.h>
40#include <sys/types.h>
41#include <errno.h>
42#include <unistd.h>
43#include <sys/ipc.h>
44#include <sys/shm.h>
45#include <sys/sem.h>
46
47#ifndef SA_RESTART
48#define SA_RESTART 0
49#endif
50
51typedef struct {
52  jmp_buf   regs;
53  sigset_t  isr_level;
54} Context_Control_overlay;
55
56void  _CPU_Signal_initialize(void);
57void  _CPU_Stray_signal(int);
58void  _CPU_ISR_Handler(int);
59
60sigset_t         _CPU_Signal_mask;
61Context_Control  _CPU_Context_Default_with_ISRs_enabled;
62Context_Control  _CPU_Context_Default_with_ISRs_disabled;
63
64/*
65 * Which cpu are we? Used by libcpu and libbsp.
66 */
67
68int cpu_number;
69
70/*PAGE
71 *
72 *  _CPU_ISR_From_CPU_Init
73 */
74
75sigset_t  posix_empty_mask;
76
77void _CPU_ISR_From_CPU_Init()
78{
79  unsigned32        i;
80  proc_ptr          old_handler;
81
82  /*
83   * Generate an empty mask to be used by disable_support
84   */
85
86  sigemptyset(&posix_empty_mask);
87 
88  /*
89   * Block all the signals except SIGTRAP for the debugger
90   * and SIGABRT for fatal errors.
91   */
92
93  (void) sigfillset(&_CPU_Signal_mask);
94  (void) sigdelset(&_CPU_Signal_mask, SIGTRAP);
95  (void) sigdelset(&_CPU_Signal_mask, SIGABRT);
96  (void) sigdelset(&_CPU_Signal_mask, SIGIOT);
97  (void) sigdelset(&_CPU_Signal_mask, SIGCONT);
98
99  _CPU_ISR_Enable(1);
100
101  /*
102   * Set the handler for all signals to be signal_handler
103   * which will then vector out to the correct handler
104   * for whichever signal actually happened. Initially
105   * set the vectors to the stray signal handler.
106   */
107
108  for (i = 0; i < CPU_INTERRUPT_NUMBER_OF_VECTORS; i++)
109      (void)_CPU_ISR_install_vector(i, _CPU_Stray_signal, &old_handler);
110
111  _CPU_Signal_initialize();
112}
113
114void _CPU_Signal_initialize( void )
115{
116  struct sigaction  act;
117  sigset_t          mask;
118
119  /* mark them all active except for TraceTrap  and Abort */
120
121  sigfillset(&mask);
122  sigdelset(&mask, SIGTRAP);
123  sigdelset(&mask, SIGABRT);
124  sigdelset(&mask, SIGIOT);
125  sigdelset(&mask, SIGCONT);
126  sigprocmask(SIG_UNBLOCK, &mask, 0);
127
128  act.sa_handler = _CPU_ISR_Handler;
129  act.sa_mask = mask;
130  act.sa_flags = SA_RESTART;
131
132  sigaction(SIGHUP, &act, 0);
133  sigaction(SIGINT, &act, 0);
134  sigaction(SIGQUIT, &act, 0);
135  sigaction(SIGILL, &act, 0);
136#ifdef SIGEMT
137  sigaction(SIGEMT, &act, 0);
138#endif
139  sigaction(SIGFPE, &act, 0);
140  sigaction(SIGKILL, &act, 0);
141  sigaction(SIGBUS, &act, 0);
142  sigaction(SIGSEGV, &act, 0);
143#ifdef SIGSYS
144  sigaction(SIGSYS, &act, 0);
145#endif
146  sigaction(SIGPIPE, &act, 0);
147  sigaction(SIGALRM, &act, 0);
148  sigaction(SIGTERM, &act, 0);
149  sigaction(SIGUSR1, &act, 0);
150  sigaction(SIGUSR2, &act, 0);
151  sigaction(SIGCHLD, &act, 0);
152  sigaction(SIGCLD, &act, 0);
153  sigaction(SIGPWR, &act, 0);
154  sigaction(SIGVTALRM, &act, 0);
155  sigaction(SIGPROF, &act, 0);
156  sigaction(SIGIO, &act, 0);
157  sigaction(SIGWINCH, &act, 0);
158  sigaction(SIGSTOP, &act, 0);
159  sigaction(SIGTTIN, &act, 0);
160  sigaction(SIGTTOU, &act, 0);
161  sigaction(SIGURG, &act, 0);
162#ifdef SIGLOST
163    sigaction(SIGLOST, &act, 0);
164#endif
165
166}
167
168/*PAGE
169 *
170 *  _CPU_Context_From_CPU_Init
171 */
172
173void _CPU_Context_From_CPU_Init()
174{
175
176#if defined(hppa1_1) && defined(RTEMS_UNIXLIB)
177    /*
178     * HACK - set the _SYSTEM_ID to 0x20c so that setjmp/longjmp
179     * will handle the full 32 floating point registers.
180     *
181     *  NOTE:  Is this a bug in HPUX9?
182     */
183
184    {
185      extern unsigned32 _SYSTEM_ID;
186
187      _SYSTEM_ID = 0x20c;
188    }
189#endif
190
191  /*
192   *  get default values to use in _CPU_Context_Initialize()
193   */
194
195  _CPU_ISR_Set_level( 0 );
196  _CPU_Context_switch(
197    &_CPU_Context_Default_with_ISRs_enabled,
198    &_CPU_Context_Default_with_ISRs_enabled
199  );
200
201  _CPU_ISR_Set_level( 1 );
202  _CPU_Context_switch(
203    &_CPU_Context_Default_with_ISRs_disabled,
204    &_CPU_Context_Default_with_ISRs_disabled
205  );
206}
207
208/*PAGE
209 *
210 *  _CPU_ISR_Get_level
211 */
212
213sigset_t GET_old_mask;
214
215unsigned32 _CPU_ISR_Get_level( void )
216{
217/*  sigset_t  old_mask; */
218   unsigned32 old_level;
219 
220  sigprocmask(0, 0, &GET_old_mask);
221 
222  if (memcmp((void *)&posix_empty_mask, (void *)&GET_old_mask, sizeof(sigset_t)))
223    old_level = 1;
224  else
225    old_level = 0;
226
227  return old_level;
228}
229
230/*  _CPU_Initialize
231 *
232 *  This routine performs processor dependent initialization.
233 *
234 *  INPUT PARAMETERS:
235 *    cpu_table       - CPU table to initialize
236 *    thread_dispatch - address of disptaching routine
237 */
238
239
240void _CPU_Initialize(
241  rtems_cpu_table  *cpu_table,
242  void            (*thread_dispatch)      /* ignored on this CPU */
243)
244{
245  /*
246   *  The thread_dispatch argument is the address of the entry point
247   *  for the routine called at the end of an ISR once it has been
248   *  decided a context switch is necessary.  On some compilation
249   *  systems it is difficult to call a high-level language routine
250   *  from assembly.  This allows us to trick these systems.
251   *
252   *  If you encounter this problem save the entry point in a CPU
253   *  dependent variable.
254   */
255
256  _CPU_Thread_dispatch_pointer = thread_dispatch;
257
258  /*
259   * XXX; If there is not an easy way to initialize the FP context
260   *      during Context_Initialize, then it is usually easier to
261   *      save an "uninitialized" FP context here and copy it to
262   *      the task's during Context_Initialize.
263   */
264
265  /* XXX: FP context initialization support */
266
267  _CPU_Table = *cpu_table;
268
269  _CPU_ISR_From_CPU_Init();
270
271  _CPU_Context_From_CPU_Init();
272
273}
274
275/*PAGE
276 *
277 *  _CPU_ISR_install_raw_handler
278 */
279
280void _CPU_ISR_install_raw_handler(
281  unsigned32  vector,
282  proc_ptr    new_handler,
283  proc_ptr   *old_handler
284)
285{
286  _CPU_Fatal_halt( 0xdeaddead );
287}
288
289/*PAGE
290 *
291 *  _CPU_ISR_install_vector
292 *
293 *  This kernel routine installs the RTEMS handler for the
294 *  specified vector.
295 *
296 *  Input parameters:
297 *    vector      - interrupt vector number
298 *    old_handler - former ISR for this vector number
299 *    new_handler - replacement ISR for this vector number
300 *
301 *  Output parameters:  NONE
302 *
303 */
304
305
306void _CPU_ISR_install_vector(
307  unsigned32  vector,
308  proc_ptr    new_handler,
309  proc_ptr   *old_handler
310)
311{
312   *old_handler = _ISR_Vector_table[ vector ];
313
314   /*
315    *  If the interrupt vector table is a table of pointer to isr entry
316    *  points, then we need to install the appropriate RTEMS interrupt
317    *  handler for this vector number.
318    */
319
320   /*
321    *  We put the actual user ISR address in '_ISR_vector_table'.  This will
322    *  be used by the _CPU_ISR_Handler so the user gets control.
323    */
324
325    _ISR_Vector_table[ vector ] = new_handler;
326}
327
328/*PAGE
329 *
330 *  _CPU_Install_interrupt_stack
331 */
332
333void _CPU_Install_interrupt_stack( void )
334{
335}
336
337/*PAGE
338 *
339 *  _CPU_Internal_threads_Idle_thread_body
340 *
341 *  NOTES:
342 *
343 *  1. This is the same as the regular CPU independent algorithm.
344 *
345 *  2. If you implement this using a "halt", "idle", or "shutdown"
346 *     instruction, then don't forget to put it in an infinite loop.
347 *
348 *  3. Be warned. Some processors with onboard DMA have been known
349 *     to stop the DMA if the CPU were put in IDLE mode.  This might
350 *     also be a problem with other on-chip peripherals.  So use this
351 *     hook with caution.
352 */
353
354void _CPU_Internal_threads_Idle_thread_body( void )
355{
356  while (1)
357    pause();
358}
359
360/*PAGE
361 *
362 *  _CPU_Context_Initialize
363 */
364
365void _CPU_Context_Initialize(
366  Context_Control  *_the_context,
367  unsigned32       *_stack_base,
368  unsigned32        _size,
369  unsigned32        _new_level,
370  void             *_entry_point
371)
372{
373  void        *source;
374  unsigned32  *addr;
375  unsigned32   jmp_addr;
376  unsigned32   _stack_low;   /* lowest "stack aligned" address */
377  unsigned32   _stack_high;  /* highest "stack aligned" address */
378  unsigned32   _the_size;
379
380  jmp_addr = (unsigned32) _entry_point;
381
382  /*
383   *  On CPUs with stacks which grow down, we build the stack
384   *  based on the _stack_high address.  On CPUs with stacks which
385   *  grow up, we build the stack based on the _stack_low address. 
386   */
387
388  _stack_low = ((unsigned32)(_stack_base) + CPU_STACK_ALIGNMENT);
389  _stack_low &= ~(CPU_STACK_ALIGNMENT - 1);
390
391  _stack_high = ((unsigned32)(_stack_base) + _size);
392  _stack_high &= ~(CPU_STACK_ALIGNMENT - 1);
393
394  _the_size = _size & ~(CPU_STACK_ALIGNMENT - 1);
395
396  /*
397   * Slam our jmp_buf template into the context we are creating
398   */
399
400  if ( _new_level == 0 )
401    source = &_CPU_Context_Default_with_ISRs_enabled;
402  else
403    source = &_CPU_Context_Default_with_ISRs_disabled;
404     
405  memcpy(_the_context, source, sizeof(Context_Control) ); /* sizeof(jmp_buf)); */
406
407  addr = (unsigned32 *)_the_context;
408
409#if defined(hppa1_1)
410  *(addr + RP_OFF) = jmp_addr;
411  *(addr + SP_OFF) = (unsigned32)(_stack_low + CPU_FRAME_SIZE);
412
413  /*
414   * See if we are using shared libraries by checking
415   * bit 30 in 24 off of newp. If bit 30 is set then
416   * we are using shared libraries and the jump address
417   * is at what 24 off of newp points to so shove that
418   * into 24 off of newp instead.
419   */
420
421  if (jmp_addr & 0x40000000) {
422    jmp_addr &= 0xfffffffc;
423     *(addr + RP_OFF) = (unsigned32)*(unsigned32 *)jmp_addr;
424  }
425#elif defined(sparc)
426
427  /*
428   *  See /usr/include/sys/stack.h in Solaris 2.3 for a nice
429   *  diagram of the stack.
430   */
431
432  asm ("ta  0x03");            /* flush registers */
433
434  *(addr + RP_OFF) = jmp_addr + ADDR_ADJ_OFFSET;
435  *(addr + SP_OFF) = (unsigned32)(_stack_high - CPU_FRAME_SIZE);
436  *(addr + FP_OFF) = (unsigned32)(_stack_high);
437
438#elif defined(i386)
439 
440    /*
441     *  This information was gathered by disassembling setjmp().
442     */
443
444    {
445      unsigned32 stack_ptr;
446
447      stack_ptr = _stack_high - CPU_FRAME_SIZE;
448
449      *(addr + EBX_OFF) = 0xFEEDFEED;
450      *(addr + ESI_OFF) = 0xDEADDEAD;
451      *(addr + EDI_OFF) = 0xDEAFDEAF;
452      *(addr + EBP_OFF) = stack_ptr;
453      *(addr + ESP_OFF) = stack_ptr;
454      *(addr + RET_OFF) = jmp_addr;
455 
456      addr = (unsigned32 *) stack_ptr;
457 
458      addr[ 0 ] = jmp_addr;
459      addr[ 1 ] = (unsigned32) stack_ptr;
460      addr[ 2 ] = (unsigned32) stack_ptr;
461    }
462
463#else
464#error "UNKNOWN CPU!!!"
465#endif
466
467}
468
469/*PAGE
470 *
471 *  _CPU_Context_restore
472 */
473
474void _CPU_Context_restore(
475  Context_Control  *next
476)
477{
478  Context_Control_overlay *nextp = (Context_Control_overlay *)next;
479
480  sigprocmask( SIG_SETMASK, &nextp->isr_level, 0 );
481  longjmp( nextp->regs, 0 );
482}
483
484/*PAGE
485 *
486 *  _CPU_Context_switch
487 */
488
489void _CPU_Context_switch(
490  Context_Control  *current,
491  Context_Control  *next
492)
493{
494  Context_Control_overlay *currentp = (Context_Control_overlay *)current;
495  Context_Control_overlay *nextp = (Context_Control_overlay *)next;
496
497  int status;
498
499  /*
500   *  Switch levels in one operation
501   */
502
503  status = sigprocmask( SIG_SETMASK, &nextp->isr_level, &currentp->isr_level );
504  if ( status )
505    _Internal_error_Occurred(
506      INTERNAL_ERROR_CORE,
507      TRUE,
508      status
509    );
510
511  if (setjmp(currentp->regs) == 0) {    /* Save the current context */
512     longjmp(nextp->regs, 0);           /* Switch to the new context */
513     if ( status )
514       _Internal_error_Occurred(
515         INTERNAL_ERROR_CORE,
516         TRUE,
517         status
518       );
519  }
520
521}
522 
523/*PAGE
524 *
525 *  _CPU_Save_float_context
526 */
527
528void _CPU_Save_float_context(
529  Context_Control_fp *fp_context
530)
531{
532}
533
534/*PAGE
535 *
536 *  _CPU_Restore_float_context
537 */
538
539void _CPU_Restore_float_context(
540  Context_Control_fp *fp_context
541)
542{
543}
544
545/*PAGE
546 *
547 *  _CPU_ISR_Disable_support
548 */
549
550unsigned32 _CPU_ISR_Disable_support(void)
551{
552  int status;
553  sigset_t  old_mask;
554
555  status = sigprocmask(SIG_BLOCK, &_CPU_Signal_mask, &old_mask);
556  if ( status )
557    _Internal_error_Occurred(
558      INTERNAL_ERROR_CORE,
559      TRUE,
560      status
561    );
562
563  if (memcmp((void *)&posix_empty_mask, (void *)&old_mask, sizeof(sigset_t)))
564    return 1;
565
566  return 0;
567}
568
569/*PAGE
570 *
571 *  _CPU_ISR_Enable
572 */
573
574void _CPU_ISR_Enable(
575  unsigned32 level
576)
577{
578  int status;
579
580  if (level == 0)
581    status = sigprocmask(SIG_UNBLOCK, &_CPU_Signal_mask, 0);
582  else
583    status = sigprocmask(SIG_BLOCK, &_CPU_Signal_mask, 0);
584
585  if ( status )
586    _Internal_error_Occurred(
587      INTERNAL_ERROR_CORE,
588      TRUE,
589      status
590    );
591}
592
593/*PAGE
594 *
595 *  _CPU_ISR_Handler
596 *
597 *  External interrupt handler.
598 *  This is installed as a UNIX signal handler.
599 *  It vectors out to specific user interrupt handlers.
600 */
601
602void _CPU_ISR_Handler(int vector)
603{
604  extern void        _Thread_Dispatch(void);
605  extern unsigned32  _Thread_Dispatch_disable_level;
606  extern boolean     _Context_Switch_necessary;
607
608
609  if (_ISR_Nest_level++ == 0) {
610      /* switch to interrupt stack */
611  }
612
613  _Thread_Dispatch_disable_level++;
614
615  if (_ISR_Vector_table[vector]) {
616     _ISR_Vector_table[vector](vector);
617  } else {
618     _CPU_Stray_signal(vector);
619  }
620
621  if (_ISR_Nest_level-- == 0) {
622      /* switch back to original stack */
623  }
624
625  _Thread_Dispatch_disable_level--;
626
627  if (_Thread_Dispatch_disable_level == 0 &&
628      (_Context_Switch_necessary || _ISR_Signals_to_thread_executing)) {
629      _CPU_ISR_Enable(0);
630      _Thread_Dispatch();
631  }
632}
633
634/*PAGE
635 *
636 *  _CPU_Stray_signal
637 */
638
639void _CPU_Stray_signal(int sig_num)
640{
641  char buffer[ 4 ];   
642
643  /*
644   *  We avoid using the stdio section of the library.
645   *  The following is generally safe.
646   */
647
648  buffer[ 0 ] = (sig_num >> 4) + 0x30;
649  buffer[ 1 ] = (sig_num & 0xf) + 0x30;
650  buffer[ 2 ] = '\n';
651
652  write( 2, "Stray signal 0x", 12 );
653  write( 2, buffer, 3 );
654 
655  /*
656   * If it was a "fatal" signal, then exit here
657   * If app code has installed a hander for one of these, then
658   * we won't call _CPU_Stray_signal, so this is ok.
659   */
660 
661  switch (sig_num) {
662      case SIGINT:
663      case SIGHUP:
664      case SIGQUIT:
665      case SIGILL:
666#ifdef SIGEMT
667      case SIGEMT:
668#endif
669      case SIGKILL:
670      case SIGBUS:
671      case SIGSEGV:
672      case SIGTERM:
673          _CPU_Fatal_error(0x100 + sig_num);
674  }
675}
676
677/*PAGE
678 *
679 *  _CPU_Fatal_error
680 */
681
682void _CPU_Fatal_error(unsigned32 error)
683{
684  setitimer(ITIMER_REAL, 0, 0);
685
686  if ( error ) {
687#ifdef RTEMS_DEBUG
688    abort();
689#endif
690    if (getenv("RTEMS_DEBUG"))
691      abort();
692  }
693
694  _exit(error);
695}
696
697/*PAGE
698 *
699 *  _CPU_ffs
700 */
701
702int _CPU_ffs(unsigned32 value)
703{
704  int output;
705  extern int ffs( int );
706
707  output = ffs(value);
708  output = output - 1;
709
710  return output;
711}
712
713
714/*
715 *  Special Purpose Routines to hide the use of UNIX system calls.
716 */
717
718#if 0
719/* XXX clock had this set of #define's */
720
721/*
722 *  In order to get the types and prototypes used in this file under
723 *  Solaris 2.3, it is necessary to pull the following magic.
724 */
725 
726#if defined(solaris)
727#warning "Ignore the undefining __STDC__ warning"
728#undef __STDC__
729#define __STDC__ 0
730#undef  _POSIX_C_SOURCE
731#endif
732#endif
733
734int _CPU_Get_clock_vector( void )
735{
736  return SIGALRM;
737}
738
739
740void _CPU_Start_clock(
741  int microseconds
742)
743{
744  struct itimerval  new;
745
746  new.it_value.tv_sec = 0;
747  new.it_value.tv_usec = microseconds;
748  new.it_interval.tv_sec = 0;
749  new.it_interval.tv_usec = microseconds;
750
751  setitimer(ITIMER_REAL, &new, 0);
752}
753
754void _CPU_Stop_clock( void )
755{
756  struct itimerval  new;
757  struct sigaction  act;
758 
759  /*
760   * Set the SIGALRM signal to ignore any last
761   * signals that might come in while we are
762   * disarming the timer and removing the interrupt
763   * vector.
764   */
765 
766  act.sa_handler = SIG_IGN;
767
768  sigaction(SIGALRM, &act, 0);
769 
770  new.it_value.tv_sec = 0;
771  new.it_value.tv_usec = 0;
772 
773  setitimer(ITIMER_REAL, &new, 0);
774}
775
776int  _CPU_SHM_Semid;
777extern       void fix_syscall_errno( void );
778
779void _CPU_SHM_Init(
780  unsigned32   maximum_nodes,
781  boolean      is_master_node,
782  void       **shm_address,
783  unsigned32  *shm_length
784)
785{
786  int          i;
787  int          shmid;
788  char        *shm_addr;
789  key_t        shm_key;
790  key_t        sem_key;
791  int          status;
792  int          shm_size;
793 
794  if (getenv("RTEMS_SHM_KEY"))
795    shm_key = strtol(getenv("RTEMS_SHM_KEY"), 0, 0);
796  else
797#ifdef RTEMS_SHM_KEY
798    shm_key = RTEMS_SHM_KEY;
799#else
800    shm_key = 0xa000;
801#endif
802 
803    if (getenv("RTEMS_SHM_SIZE"))
804      shm_size = strtol(getenv("RTEMS_SHM_SIZE"), 0, 0);
805    else
806#ifdef RTEMS_SHM_SIZE
807      shm_size = RTEMS_SHM_SIZE;
808#else
809      shm_size = 64 * 1024;
810#endif
811 
812    if (getenv("RTEMS_SHM_SEMAPHORE_KEY"))
813      sem_key = strtol(getenv("RTEMS_SHM_SEMAPHORE_KEY"), 0, 0);
814    else
815#ifdef RTEMS_SHM_SEMAPHORE_KEY
816      sem_key = RTEMS_SHM_SEMAPHORE_KEY;
817#else
818      sem_key = 0xa001;
819#endif
820 
821    shmid = shmget(shm_key, shm_size, IPC_CREAT | 0660);
822    if ( shmid == -1 ) {
823      fix_syscall_errno(); /* in case of newlib */
824      perror( "shmget" );
825      _CPU_Fatal_halt( 0xdead0001 );
826    }
827 
828    shm_addr = shmat(shmid, (char *)0, SHM_RND);
829    if ( shm_addr == (void *)-1 ) {
830      fix_syscall_errno(); /* in case of newlib */
831      perror( "shmat" );
832      _CPU_Fatal_halt( 0xdead0002 );
833    }
834 
835    _CPU_SHM_Semid = semget(sem_key, maximum_nodes + 1, IPC_CREAT | 0660);
836    if ( _CPU_SHM_Semid == -1 ) {
837      fix_syscall_errno(); /* in case of newlib */
838      perror( "semget" );
839      _CPU_Fatal_halt( 0xdead0003 );
840    }
841 
842    if ( is_master_node ) {
843      for ( i=0 ; i <= maximum_nodes ; i++ ) {
844#if defined(solaris2)
845        union semun {
846          int val;
847          struct semid_ds *buf;
848          ushort *array;
849        } help;
850 
851        help.val = 1;
852        status = semctl( _CPU_SHM_Semid, i, SETVAL, help );
853#endif
854#if defined(hpux)
855        status = semctl( _CPU_SHM_Semid, i, SETVAL, 1 );
856#endif
857 
858        fix_syscall_errno(); /* in case of newlib */
859        if ( status == -1 ) {
860          _CPU_Fatal_halt( 0xdead0004 );
861        }
862      }
863    }
864 
865  *shm_address = shm_addr;
866  *shm_length = shm_size;
867
868}
869
870int _CPU_Get_pid( void )
871{
872  return getpid();
873}
874
875/*
876 * Define this to use signals for MPCI shared memory driver.
877 * If undefined, the shared memory driver will poll from the
878 * clock interrupt.
879 * Ref: ../shmsupp/getcfg.c
880 *
881 * BEWARE:: many UN*X kernels and debuggers become severely confused when
882 *          debugging programs which use signals.  The problem is *much*
883 *          worse when using multiple signals, since ptrace(2) tends to
884 *          drop all signals except 1 in the case of multiples.
885 *          On hpux9, this problem was so bad, we couldn't use interrupts
886 *          with the shared memory driver if we ever hoped to debug
887 *          RTEMS programs.
888 *          Maybe systems that use /proc don't have this problem...
889 */
890 
891 
892int _CPU_SHM_Get_vector( void )
893{
894#ifdef CPU_USE_SHM_INTERRUPTS
895  return SIGUSR1;
896#else
897  return 0;
898#endif
899}
900
901void _CPU_SHM_Send_interrupt(
902  int pid,
903  int vector
904)
905{
906  kill((pid_t) pid, vector);
907}
908
909void _CPU_SHM_Lock(
910  int semaphore
911)
912{
913  struct sembuf      sb;
914  int                status;
915 
916  sb.sem_num = semaphore;
917  sb.sem_op  = -1;
918  sb.sem_flg = 0;
919 
920  while (1) {
921    status = semop(_CPU_SHM_Semid, &sb, 1);
922    if ( status >= 0 )
923      break;
924    if ( status == -1 ) {
925       fix_syscall_errno();    /* in case of newlib */
926        if (errno == EINTR)
927            continue;
928        perror("shm lock");
929        _CPU_Fatal_halt( 0xdead0005 );
930    }
931  }
932
933}
934
935void _CPU_SHM_Unlock(
936  int semaphore
937)
938{
939  struct sembuf  sb;
940  int            status;
941 
942  sb.sem_num = semaphore;
943  sb.sem_op  = 1;
944  sb.sem_flg = 0;
945 
946  while (1) {
947    status = semop(_CPU_SHM_Semid, &sb, 1);
948    if ( status >= 0 )
949      break;
950 
951    if ( status == -1 ) {
952      fix_syscall_errno();    /* in case of newlib */
953      if (errno == EINTR)
954          continue;
955      perror("shm unlock");
956      _CPU_Fatal_halt( 0xdead0006 );
957    }
958  }
959
960}
Note: See TracBrowser for help on using the repository browser.