Example #1
0
int
_papi_hwi_initialize_thread( ThreadInfo_t ** dest, int tid )
{
	int retval;
	ThreadInfo_t *thread;
	int i;

	if ( ( thread = allocate_thread( tid  ) ) == NULL ) {
		*dest = NULL;
		return PAPI_ENOMEM;
	}

	/* Call the substrate to fill in anything special. */

	for ( i = 0; i < papi_num_components; i++ ) {
		retval = _papi_hwd[i]->init( thread->context[i] );
		if ( retval ) {
			free_thread( &thread );
			*dest = NULL;
			return retval;
		}
	}

	insert_thread( thread, tid );

	*dest = thread;
	return PAPI_OK;
}
Example #2
0
void Timer::suicide()
{
    if(m_impl)
    {
        TimerThread* thread = allocate_thread();
        thread->active_timers.remove(m_impl);
        thread->spare_timers.append(m_impl);
        m_impl->init();
        m = nullptr;
    }
    delete this;
}
Example #3
0
void Timer::cleanup()
{
    auto thread = allocate_thread();

    for(;;)
    {
        auto timer = thread->spare_timers.first();
        if(!timer)
            break;
        thread->spare_timers.remove(timer);
        delete timer;
    }
}
Example #4
0
Timer::~Timer()
{
    if(m_impl)
    {
        TimerThread* thread = allocate_thread();
        if(thread)
        {
            thread->active_timers.remove(m_impl);
        }

        delete m_impl;
    }
}
Example #5
0
unsigned long Timer::runTimers(TimerThreadId* thread_id)
{
    TimerThread* thread;
    if(thread_id)
    {
        thread = (TimerThread*) thread_id;
    }
    else
    {
        thread = allocate_thread();
    }

    unsigned long long curr_time = current_nanoseconds();

    unsigned long min_time = numeric_limits<unsigned long>::max();
    auto timer = thread->active_timers.first();
    while(timer)
    {
        //Make sure we fetch the next_timer before the callback
        //so that the timer could be removed from the active_timers list.
        auto next_timer = timer->next();
        if(timer->is_running && timer->interval >= 0)
        {
            if(curr_time >= timer->wakeup_time)
            {
                timer->callback(timer->iface, timer->callback_data);
                timer->wakeup_time = curr_time + timer->interval;
            }

            if(timer->wakeup_time < min_time)
            {
                min_time = timer->wakeup_time;
            }
        }
        timer = next_timer;
    }

    if(min_time > curr_time)
    {
        return (min_time - curr_time);
    }
    return 0;
}
Example #6
0
Timer::Timer(unsigned long interval)
{
    TimerThread* thread = allocate_thread();
    if(!thread)
        return;

    if(thread->spare_timers.empty())
    {
        m = new TimerImpl;
    }
    else
    {
        m = thread->spare_timers.last();
        thread->spare_timers.remove(m_impl);
    }

    m_impl->iface = this;
    setInterval(interval);

    thread->active_timers.append(m_impl);
}
Example #7
0
TimerThreadId* Timer::reserveThreadId()
{
    auto thread = allocate_thread();
    thread->is_reserved = true;
    return (TimerThreadId*) thread;
}
Example #8
0
int
system_call_implementation(void)
{
 register int schedule=0;
 /*!< System calls may set this variable to 1. The variable is used as
      input to the scheduler to indicate if scheduling is necessary. */
 switch(SYSCALL_ARGUMENTS.rax)
 {
  case SYSCALL_PRINTS:
  {
   kprints((char*) (SYSCALL_ARGUMENTS.rdi));
   SYSCALL_ARGUMENTS.rax = ALL_OK;

   break;
  }

  case SYSCALL_PRINTHEX:
  {
   kprinthex(SYSCALL_ARGUMENTS.rdi);
   SYSCALL_ARGUMENTS.rax = ALL_OK;
   break;
  }

  case SYSCALL_DEBUGGER:
  {
   /* Enable the bochs iodevice and force a return to the debugger. */
   outw(0x8a00, 0x8a00);
   outw(0x8a00, 0x8ae0);

   SYSCALL_ARGUMENTS.rax = ALL_OK;
   break;
  }

	case SYSCALL_VERSION: {
		SYSCALL_ARGUMENTS.rax = KERNEL_VERSION;
		break;
	}

	case SYSCALL_CREATEPROCESS: {

		int process_number, thread_number;
		long int executable_number = SYSCALL_ARGUMENTS.rdi;
		struct prepare_process_return_value prepare_process_ret_val;


		for (process_number = 0; process_number < MAX_NUMBER_OF_PROCESSES && process_table[process_number].threads > 0; process_number++) {
		}
		prepare_process_ret_val = prepare_process(
				executable_table[executable_number].elf_image,
				process_number,
				executable_table[executable_number].memory_footprint_size);

		if(0 == prepare_process_ret_val.first_instruction_address) {
			kprints("Error starting image\n");
		}

		process_table[process_number].parent = thread_table[cpu_private_data.thread_index].data.owner;

		thread_number = allocate_thread();

		thread_table[thread_number].data.owner = process_number;
		thread_table[thread_number].data.registers.integer_registers.rflags = 0x200;
		thread_table[thread_number].data.registers.integer_registers.rip = prepare_process_ret_val.first_instruction_address;

		process_table[process_number].threads += 1;

		SYSCALL_ARGUMENTS.rax = ALL_OK;

		thread_queue_enqueue(&ready_queue,thread_number);
		/*cpu_private_data.thread_index = thread_number;*/


		break;
	}
	case SYSCALL_TERMINATE:
	{
		int i;
		int owner_process = thread_table[cpu_private_data.thread_index].data.owner;
		int parent_process = process_table[owner_process].parent;

		thread_table[cpu_private_data.thread_index].data.owner = -1; /* Terminate Thread */

		process_table[owner_process].threads -= 1; /* Decrement Thread count */

		if(process_table[owner_process].threads < 1) {
			cleanup_process(owner_process);
		}

		for(i=0; i < MAX_NUMBER_OF_THREADS && thread_table[i].data.owner != parent_process; i++) {
		}

		/*cpu_private_data.thread_index = i;*/
		/*thread_queue_dequeue(&ready_queue);*/
		schedule = 1;

		break;

	}


  /* Do not touch any lines above or including this line. */

  /* Add the implementation of more system calls here. */


  /* Do not touch any lines below or including this line. */
  default:
  {
   /* No system call defined. */
   SYSCALL_ARGUMENTS.rax = ERROR_ILLEGAL_SYSCALL;
  }
 }

 return schedule;
}