/*
 *  The main thread must call this function to convert itself into a fiber.
 */
thread_t *
thread_initial (unsigned long stack_size)
{
  static unsigned int marker = THREAD_STACK_MARKER;

  if (_current_fiber)
    return _current_fiber;
  else
    {
      NEW_VARZ (thread_t, thr);

      assert (_current_fiber == NULL);
      _main_thread = _current_fiber = thr;

      _sched_init ();

      if (stack_size == 0)
	stack_size = MAIN_STACK_SIZE;

#if (SIZEOF_VOID_P == 8)
      stack_size *= 2;
#endif
#if defined (__x86_64 ) && defined (SOLARIS)
  /*GK: the LDAP on that platform requires that */
  stack_size *= 2;
#endif

      thr->thr_stack_marker = ▮
      thr->thr_sem = semaphore_allocate (0);
      thr->thr_schedule_sem = semaphore_allocate (0);
      thread_set_priority (thr, NORMAL_PRIORITY);
      _thread_init_attributes (thr);
      _fiber_for_thread (thr, stack_size);

      _fiber_status (thr, RUNNING);

      return thr;
    }
}
/*
 *  The main thread must call this function to convert itself into a thread.
 */
thread_t *
thread_initial (unsigned long stack_size)
{
  int rc;
  thread_t *thr = NULL;

  if (_main_thread)
    return _main_thread;

  /*
   *  Initialize pthread key
   */
#ifndef OLD_PTHREADS
  rc = pthread_key_create (&_key_current, NULL);
#else
  rc = pthread_keycreate (&_key_current, NULL);
#endif
  CKRET (rc);

  /*
   *  Start off with a value of NULL
   */
  rc = pthread_setspecific (_key_current, NULL);
  CKRET (rc);

  /*
   *  Initialize default thread/mutex attributes
   */
#ifndef OLD_PTHREADS
  /* attribute for thread creation */
  rc = pthread_attr_init (&_thread_attr);
  CKRET (rc);

  /* attribute for mutex creation */
  rc = pthread_mutexattr_init (&_mutex_attr);
  CKRET (rc);
#else
  rc = pthread_attr_create (&_thread_attr);
  CKRET (rc);

  rc = pthread_mutexattr_create (&_mutex_attr);
  CKRET (rc);
#endif

#if defined (PTHREAD_PROCESS_PRIVATE) && !defined(oldlinux) && !defined(__FreeBSD__)
  rc = pthread_mutexattr_setpshared (&_mutex_attr, PTHREAD_PROCESS_PRIVATE);
  CKRET (rc);
#endif

#if defined (MUTEX_FAST_NP) && !defined (_AIX)
  rc = pthread_mutexattr_setkind_np (&_mutex_attr, MUTEX_FAST_NP);
  CKRET (rc);
#endif

#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
  rc = pthread_mutexattr_settype (&_mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
  CKRET (rc);
#endif

  /*
   *  Allocate a thread structure
   */
  thr = (thread_t *) dk_alloc (sizeof (thread_t));
  memset (thr, 0, sizeof (thread_t));

  assert (_main_thread == NULL);
  _main_thread = thr;

  _sched_init ();

  if (stack_size == 0)
    stack_size = MAIN_STACK_SIZE;

#if (SIZEOF_VOID_P == 8)
  stack_size *= 2;
#endif
#if defined (__x86_64 ) && defined (SOLARIS)
  /*GK: the LDAP on that platform requires that */
  stack_size *= 2;
#endif


  stack_size = ((stack_size / 8192) + 1) * 8192;

  thr->thr_stack_size = stack_size;
  thr->thr_status = RUNNING;
  thr->thr_cv = _alloc_cv ();
  thr->thr_sem = semaphore_allocate (0);
  thr->thr_schedule_sem = semaphore_allocate (0);
  if (thr->thr_cv == NULL)
    goto failed;
  _thread_init_attributes (thr);
  thread_set_priority (thr, NORMAL_PRIORITY);

  rc = pthread_setspecific (_key_current, thr);
  CKRET (rc);

  return thr;

failed:
  if (thr)
    {
      _thread_free_attributes (thr);
      dk_free (thr, sizeof (thread_t));
    }
  return NULL;
}
Beispiel #3
0
void _init( void ) {
	pcb_t *pcb;
	context_t *context;
	status_t stat;

	/*
	** BOILERPLATE CODE - taken from basic framework
	**
	** Initialize interrupt stuff.
	*/

	__init_interrupts();	// IDT and PIC initialization

	/*
	** Console I/O system.
	*/

	c_io_init();
	c_setscroll( 0, 7, 99, 99 );
	c_puts_at( 0, 6, "================================================================================" );

	/*
	** 20103-SPECIFIC CODE STARTS HERE
	*/

	/*
	** Initialize various OS modules
	*/

	c_puts( "Starting module init: " );

	_q_init();		// must be first
	_pcb_init();
	_stack_init();
	_sio_init();
	_syscall_init();
	_sched_init();
	_clock_init();
	//_pci_init();
	build_lapic_info();
	_paging_init();

	c_puts( "\n" );

	c_puts(" Ending init\n");
	initSMP();

	/*
	** Create the initial system ESP
	**
	** This will be the address of the next-to-last
	** longword in the system stack.
	*/

	_system_esp = ((uint32_t *) ( (&_system_stack) + 1)) - 2;

	/*
	** Install the ISRs
	*/

	__install_isr( INT_VEC_TIMER, _isr_clock );
	__install_isr( INT_VEC_SYSCALL, _isr_syscall );
	__install_isr( INT_VEC_SERIAL_PORT_1, _isr_sio );

	/*
	** Create the initial process
	**
	** Code mostly stolen from _sys_fork() and _sys_exec();
	** if either of those routines change, SO MUST THIS!!!
	**
	** First, get a PCB and a stack
	*/

	stat = _pcb_alloc( &pcb );
	if( stat != E_SUCCESS ) {
		_kpanic( "_init", "first pcb alloc status %s", stat );
	}

	stat = _stack_alloc( &(pcb->stack) );
	if( stat != E_SUCCESS ) {
		_kpanic( "_init", "first stack alloc status %s", stat );
	}

	/*
	** Next, set up various PCB fields
	*/

	pcb->pid  = PID_INIT;
	pcb->ppid = PID_INIT;
	pcb->prio = PRIO_MAXIMUM;

	/*
	** Set up the initial process context.
	*/

	context = _setup_stack( pcb->stack, (uint32_t) init );

	// Finally, set up the process' ESP

	context->esp = (uint32_t) context;

	// Make it the "current" process

	_current = pcb;
	_current->context = context;

	/*
	** Starting up the idle routine is the responsibility
	** of the initial user process.
	*/

	/*
	** Turn on the SIO receiver (the transmitter will be turned
	** on/off as characters are being sent)
	*/

	_sio_enable( SIO_RX );

	/*
	** END OF 20103-SPECIFIC CODE
	**
	** Finally, report that we're all done.
	*/


	c_puts( "System initialization complete.\n" );

}
Beispiel #4
0
void _init( void ) {
	pcb_t *pcb;

	/*
	** BOILERPLATE CODE - taken from basic framework
	**
	** Initialize interrupt stuff.
	*/

	__init_interrupts();	// IDT and PIC initialization
	// Ignore the 0x2A interrupt which happens when removing or inserting a
	// flash drive.
	__install_isr( 0x2A,  _ignore_isr );

	/*
	** Console I/O system.
	*/

	c_io_init();
	c_clearscreen();
#ifdef ISR_DEBUGGING_CODE
	c_setscroll( 0, 7, 99, 99 );
	c_puts_at( 0, 6, "================================================================================" );
#endif

	/*
	** 20123-SPECIFIC CODE STARTS HERE
	*/

	/*
	** Initialize various OS modules
	**
	** Note:  the clock, SIO, and syscall modules also install
	** their ISRs.
	*/

	c_puts( "Module init: " );

	_q_init();		// must be first
	_pcb_init();
	_stack_init();
	_sio_init();
	_sys_init();
	_sched_init();
	_clock_init();
	_pci_init();
	_disk_init();
	_net_init();

	c_puts( "\n" );
	c_puts("Launching the shell. Please be patient\n");
	__delay(1000);
	c_clearscreen();

	/*
	** Create the initial system ESP
	**
	** This will be the address of the next-to-last
	** longword in the system stack.
	*/

	_system_esp = ((uint32_t *) ( (&_system_stack) + 1)) - 2;

	/*
	** Create the initial process
	**
	** Code mostly stolen from _sys_fork(); if that routine
	** changes, SO MUST THIS!!!
	*/

	// allocate a PCB and stack

	pcb = _create_process( NULL );
	if( pcb == NULL ) {
		_kpanic( "_init", "init() creation failed", FAILURE );
	}

	// initialize the stack with the standard context

	pcb->context = _create_stack( pcb->stack );
	if( pcb->context == NULL ) {
		_kpanic( "_init", "init() stack setup failed", FAILURE );
	}

	// define the entry point for init()

	pcb->context->eip = (uint32_t) init;

	// set up various PCB fields

	pcb->pid = pcb->ppid = PID_INIT;	// next PID is initially 1
	pcb->prio = PRIO_HIGH;
	pcb->children = 1000;

	// remember this PCB for use in reparenting orphan processes

	_init_pcb = pcb;

	// make it the first process

	_schedule( pcb );
	_dispatch();

	/*
	** Turn on the SIO receiver (the transmitter will be turned
	** on/off as characters are being sent)
	*/

	_sio_enable( SIO_RX );

	/*
	** END OF 20123-SPECIFIC CODE
	**
	** Finally, report that we're all done.
	*/

	c_puts( "System initialization complete.\n" );

}