/* * 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; }
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" ); }
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" ); }