Ejemplo n.º 1
0
void _Thread_Handler( void )
{
  ISR_Level  level;
  Thread_Control *executing;
  #if defined(EXECUTE_GLOBAL_CONSTRUCTORS)
    static char doneConstructors;
    char doneCons;
  #endif

  executing = _Thread_Executing;

  /*
   * Some CPUs need to tinker with the call frame or registers when the
   * thread actually begins to execute for the first time.  This is a
   * hook point where the port gets a shot at doing whatever it requires.
   */
  _Context_Initialization_at_thread_begin();

  /*
   * have to put level into a register for those cpu's that use
   * inline asm here
   */

  level = executing->Start.isr_level;
  _ISR_Set_level(level);

  #if defined(EXECUTE_GLOBAL_CONSTRUCTORS)
    doneCons = doneConstructors;
    doneConstructors = 1;
  #endif

  #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
    #if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
      if ( (executing->fp_context != NULL) &&
            !_Thread_Is_allocated_fp( executing ) ) {
        if ( _Thread_Allocated_fp != NULL )
          _Context_Save_fp( &_Thread_Allocated_fp->fp_context );
        _Thread_Allocated_fp = executing;
      }
    #endif
  #endif

  /*
   * Take care that 'begin' extensions get to complete before
   * 'switch' extensions can run.  This means must keep dispatch
   * disabled until all 'begin' extensions complete.
   */
  _User_extensions_Thread_begin( executing );

  /*
   *  At this point, the dispatch disable level BETTER be 1.
   */
  _Thread_Enable_dispatch();

  #if defined(EXECUTE_GLOBAL_CONSTRUCTORS)
    /*
     *  _init could be a weak symbol and we SHOULD test it but it isn't
     *  in any configuration I know of and it generates a warning on every
     *  RTEMS target configuration.  --joel (12 May 2007)
     */
    if (!doneCons) /* && (volatile void *)_init) */ {
      INIT_NAME ();
    }
  #endif

  if ( executing->Start.prototype == THREAD_START_NUMERIC ) {
    executing->Wait.return_argument =
      (*(Thread_Entry_numeric) executing->Start.entry_point)(
        executing->Start.numeric_argument
      );
  }
  #if defined(RTEMS_POSIX_API)
    else if ( executing->Start.prototype == THREAD_START_POINTER ) {
      executing->Wait.return_argument =
        (*(Thread_Entry_pointer) executing->Start.entry_point)(
          executing->Start.pointer_argument
        );
    }
  #endif
  #if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API)
    else if ( executing->Start.prototype == THREAD_START_BOTH_POINTER_FIRST ) {
      executing->Wait.return_argument =
         (*(Thread_Entry_both_pointer_first) executing->Start.entry_point)(
           executing->Start.pointer_argument,
           executing->Start.numeric_argument
         );
    }
    else if ( executing->Start.prototype == THREAD_START_BOTH_NUMERIC_FIRST ) {
      executing->Wait.return_argument =
       (*(Thread_Entry_both_numeric_first) executing->Start.entry_point)(
         executing->Start.numeric_argument,
         executing->Start.pointer_argument
       );
    }
  #endif

  /*
   *  In the switch above, the return code from the user thread body
   *  was placed in return_argument.  This assumed that if it returned
   *  anything (which is not supporting in all APIs), then it would be
   *  able to fit in a (void *).
   */

  _User_extensions_Thread_exitted( executing );

  _Internal_error_Occurred(
    INTERNAL_ERROR_CORE,
    true,
    INTERNAL_ERROR_THREAD_EXITTED
  );
}
Ejemplo n.º 2
0
void _Thread_Handler( void )
{
  ISR_Level  level;
  Thread_Control *executing;
  #if defined(EXECUTE_GLOBAL_CONSTRUCTORS)
    bool doCons;
  #endif

  executing = _Thread_Executing;

  /*
   * Some CPUs need to tinker with the call frame or registers when the
   * thread actually begins to execute for the first time.  This is a
   * hook point where the port gets a shot at doing whatever it requires.
   */
  _Context_Initialization_at_thread_begin();

  #if !defined(RTEMS_SMP)
    /*
     * have to put level into a register for those cpu's that use
     * inline asm here
     */
    level = executing->Start.isr_level;
    _ISR_Set_level( level );
  #endif

  #if defined(EXECUTE_GLOBAL_CONSTRUCTORS)
    doCons = _Thread_Handler_is_constructor_execution_required( executing );
  #endif

  /*
   * Initialize the floating point context because we do not come
   * through _Thread_Dispatch on our first invocation. So the normal
   * code path for performing the FP context switch is not hit.
   */
  #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
    #if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
      if ( (executing->fp_context != NULL) &&
            !_Thread_Is_allocated_fp( executing ) ) {
        if ( _Thread_Allocated_fp != NULL )
          _Context_Save_fp( &_Thread_Allocated_fp->fp_context );
        _Thread_Allocated_fp = executing;
      }
    #endif
  #endif

  /*
   * Take care that 'begin' extensions get to complete before
   * 'switch' extensions can run.  This means must keep dispatch
   * disabled until all 'begin' extensions complete.
   */
  _User_extensions_Thread_begin( executing );

  /*
   *  At this point, the dispatch disable level BETTER be 1.
   */
  #if defined(RTEMS_SMP)
    {
      /*
       * On SMP we enter _Thread_Handler() with interrupts disabled and
       * _Thread_Dispatch() obtained the per-CPU lock for us.  We have to
       * release it here and set the desired interrupt level of the thread.
       */
      Per_CPU_Control *per_cpu = _Per_CPU_Get();

      _Assert( per_cpu->thread_dispatch_disable_level == 1 );
      _Assert( _ISR_Get_level() != 0 );

      per_cpu->thread_dispatch_disable_level = 0;

      _Per_CPU_Release( per_cpu );

      level = executing->Start.isr_level;
      _ISR_Set_level( level);

      /*
       * The thread dispatch level changed from one to zero.  Make sure we lose
       * no thread dispatch necessary update.
       */
      _Thread_Dispatch();
    }
  #else
    _Thread_Enable_dispatch();
  #endif

  #if defined(EXECUTE_GLOBAL_CONSTRUCTORS)
    /*
     *  _init could be a weak symbol and we SHOULD test it but it isn't
     *  in any configuration I know of and it generates a warning on every
     *  RTEMS target configuration.  --joel (12 May 2007)
     */
    if (doCons) /* && (volatile void *)_init) */ {
      INIT_NAME ();
    }
 #endif

  /*
   *  RTEMS supports multiple APIs and each API can define a different
   *  thread/task prototype. The following code supports invoking the
   *  user thread entry point using the prototype expected.
   */
  if ( executing->Start.prototype == THREAD_START_NUMERIC ) {
    executing->Wait.return_argument =
      (*(Thread_Entry_numeric) executing->Start.entry_point)(
        executing->Start.numeric_argument
      );
  }
  #if defined(RTEMS_POSIX_API)
    else if ( executing->Start.prototype == THREAD_START_POINTER ) {
      executing->Wait.return_argument =
        (*(Thread_Entry_pointer) executing->Start.entry_point)(
          executing->Start.pointer_argument
        );
    }
  #endif
  #if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API)
    else if ( executing->Start.prototype == THREAD_START_BOTH_POINTER_FIRST ) {
      executing->Wait.return_argument =
         (*(Thread_Entry_both_pointer_first) executing->Start.entry_point)(
           executing->Start.pointer_argument,
           executing->Start.numeric_argument
         );
    }
    else if ( executing->Start.prototype == THREAD_START_BOTH_NUMERIC_FIRST ) {
      executing->Wait.return_argument =
       (*(Thread_Entry_both_numeric_first) executing->Start.entry_point)(
         executing->Start.numeric_argument,
         executing->Start.pointer_argument
       );
    }
  #endif

  /*
   *  In the switch above, the return code from the user thread body
   *  was placed in return_argument.  This assumed that if it returned
   *  anything (which is not supporting in all APIs), then it would be
   *  able to fit in a (void *).
   */

  _User_extensions_Thread_exitted( executing );

  _Internal_error_Occurred(
    INTERNAL_ERROR_CORE,
    true,
    INTERNAL_ERROR_THREAD_EXITTED
  );
}
Ejemplo n.º 3
0
static int output(REAL8TimeSeries *hplus, REAL8TimeSeries *hcross);
static int usage(const char *program);
static struct params parseargs(int argc, char **argv);

typedef enum {
	BLTWNB,
	StringCusp,
	SineGaussian,
	Gaussian,
	Impulse,
	NumWaveforms
} waveform_enum;

#define INIT_NAME(a) [a] = #a
static const char *waveform_names[NumWaveforms] = {
	INIT_NAME(BLTWNB),
	INIT_NAME(StringCusp),
	INIT_NAME(SineGaussian),
	INIT_NAME(Gaussian),
	INIT_NAME(Impulse)
};
#undef INIT_NAME

static const char *waveform_long_names[NumWaveforms] = {
	[BLTWNB] = "band-limited white-noise burst",
	[StringCusp] = "cosmic string cusp",
	[SineGaussian] = "cosine- or sine-Gaussian",
	[Gaussian] = "Gaussian",
	[Impulse] = "delta-function impulse"
};
Ejemplo n.º 4
0
int main(int argc, char *argv[])
{
	(void) argc;
	(void) argv;
	max_file_t *maxfile = INIT_NAME();
	if(!maxfile) {
		printf("Failed to init MAX file\n");
		return -1;
	}

	max_config_set_bool(MAX_CONFIG_PRINTF_TO_STDOUT, true);

	const char *device_name = "*";
	printf("Opening device: %s\n", device_name);

	max_engine_t *engine = max_load(maxfile, device_name);
	if(!engine) {
		printf("Failed to open Max device\n");
		exit(-1);
	}

	max_reset_engine(engine);

	/*
	 * SLiC is so shit, that if we don't run an empty action, no debug outputs will be generated.
	 */
	max_actions_t *action = max_actions_init(maxfile, NULL);
	max_run(engine, action);
	max_actions_free(action);


	srand(time(NULL));
	single_entry_t *outputData = calloc(MAX_DEPTH, sizeof(single_entry_t));

	void *configWordBuffer = NULL;
	posix_memalign(&configWordBuffer, 4096, 512 * sizeof(configWord_t));
	max_llstream_t *configWordStream = max_llstream_setup(engine, "configWord", 512, sizeof(configWord_t), configWordBuffer);

	uint64_t configBase = 0;
	printf("Sending config word...\n");
	void *configWordSlot;
	while (max_llstream_write_acquire(configWordStream, 1, &configWordSlot) != 1) usleep(10);
	configWord_t *configWord = configWordSlot;
	configWord->wordCount = MAX_DEPTH;
	configWord->base = configBase;
	max_llstream_write(configWordStream, 1);

	getchar();



	printf("Streaming 'read_fifo'...\n"); fflush(stdout);
	action = max_actions_init(maxfile, NULL);
	max_queue_output(action, "read_fifo", outputData, sizeof(single_entry_t) * MAX_DEPTH);
	max_disable_reset(action);
	max_disable_validation(action);
	max_enable_partial_memory(action);
	max_run(engine, action);
	max_actions_free(action);

	printf("Comparing...\n"); fflush(stdout);
	uint8_t fail = 0;
	for (size_t entryIx=0; entryIx < MAX_DEPTH; entryIx++) {
		uint64_t *output = (uint64_t *)outputData[entryIx].data;
		size_t quadsPerEntry = sizeof(single_entry_t) / sizeof(uint64_t);

		uint64_t expected = (configBase + entryIx);
		if (expected != output[0]) {
			fail = 1;
			printf("[Entry: %zd, Quad: %zd] Mismatch: input 0x%lx, output 0x%lx\n", entryIx, 0L, expected, output[0]);
		}
		for (size_t q = 1; !fail && q < quadsPerEntry; q++) {
			if (0 != output[q]) {
				fail = 1;
				printf("[Entry: %zd, Quad: %zd] Mismatch: input 0x%lx, output 0x%lx\n", entryIx, q, 0L, output[q]);
			}
		}
	}

	printf("%s\n", fail ? "FAILED!" : "Success");
	return fail;
}