Exemple #1
0
void timer_adjust(mame_timer *which, double duration, int param, double period)
{
	double time = get_relative_time();

	/* if this is the callback timer, mark it modified */
	if (which == callback_timer)
		callback_timer_modified = 1;

	/* compute the time of the next firing and insert into the list */
	which->callback_param = param;
	which->enabled = 1;

	/* set the start and expire times */
	which->start = time;
	which->expire = time + duration;
	which->period = period;

	/* remove and re-insert the timer in its new order */
	timer_list_remove(which);
	timer_list_insert(which);

	/* if this was inserted as the head, abort the current timeslice and resync */
LOG(("timer_adjust %08X to expire @ %.9f\n", (UINT32)which, which->expire));
	if (which == timer_head && cpu_getexecutingcpu() >= 0)
		activecpu_abort_timeslice();
}
Exemple #2
0
void timer_adjust_periodic(emu_timer *which, attotime start_delay, INT32 param, attotime period)
{
	attotime time = get_current_time();

	/* if this is the callback timer, mark it modified */
	if (which == callback_timer)
		callback_timer_modified = TRUE;

	/* compute the time of the next firing and insert into the list */
	which->param = param;
	which->enabled = TRUE;

	/* clamp negative times to 0 */
	if (start_delay.seconds < 0)
		start_delay = attotime_zero;

	/* set the start and expire times */
	which->start = time;
	which->expire = attotime_add(time, start_delay);
	which->period = period;

	/* remove and re-insert the timer in its new order */
	timer_list_remove(which);
	timer_list_insert(which);

	/* if this was inserted as the head, abort the current timeslice and resync */
	LOG(("timer_adjust_oneshot %s.%s:%d to expire @ %s\n", which->file, which->func, which->line, attotime_string(which->expire, 9)));
	if (which == timer_head && cpu_getexecutingcpu() >= 0)
		activecpu_abort_timeslice();
}
Exemple #3
0
static STATE_POSTLOAD( timer_postload )
{
	emu_timer *privlist = NULL;
	emu_timer *t;

	/* remove all timers and make a private list */
	while (timer_head != NULL)
	{
		t = timer_head;

		/* temporary timers go away entirely */
		if (t->temporary)
			timer_remove(t);

		/* permanent ones get added to our private list */
		else
		{
			timer_list_remove(t);
			t->next = privlist;
			privlist = t;
		}
	}

	/* now add them all back in; this effectively re-sorts them by time */
	while (privlist != NULL)
	{
		t = privlist;
		privlist = t->next;
		timer_list_insert(t);
	}
}
Exemple #4
0
void mame_timer_adjust(mame_timer *which, mame_time duration, int param, mame_time period)
{
	mame_time time = get_current_time();

	/* error if this is an inactive timer */
	if (which->tag == -1)
	{
		printf("mame_timer_adjust: adjusting an inactive timer!\n");
		logerror("mame_timer_adjust: adjusting an inactive timer!\n");
		return;
	}

	/* if this is the callback timer, mark it modified */
	if (which == callback_timer)
		callback_timer_modified = 1;

	/* compute the time of the next firing and insert into the list */
	which->callback_param = param;
	which->enabled = 1;

	/* set the start and expire times */
	which->start = time;
	which->expire = add_mame_times(time, duration);
	which->period = period;

	/* remove and re-insert the timer in its new order */
	timer_list_remove(which);
	timer_list_insert(which);

	/* if this was inserted as the head, abort the current timeslice and resync */
	LOG(("timer_adjust %s:%d to expire @ %.9f\n", which->file, which->line, mame_time_to_double(which->expire)));
	if (which == timer_head && cpu_getexecutingcpu() >= 0)
		activecpu_abort_timeslice();
}
/**@brief Function for handling the timer list deletions.
 *
 * @return     TRUE if Capture Compare register must be updated, FALSE otherwise.
 */
static bool list_deletions_handler(void)
{
    timer_node_t * p_timer_old_head;
    uint8_t        user_id;

    // Remember the old head, so as to decide if new compare needs to be set.
    p_timer_old_head = mp_timer_id_head;

    user_id = m_user_array_size;
    while (user_id--)
    {
        timer_user_t * p_user         = &mp_users[user_id];
        uint8_t        user_ops_first = p_user->first;
        
        while (user_ops_first != p_user->last)
        {
            timer_node_t *    p_timer;
            timer_user_op_t * p_user_op = &p_user->p_user_op_queue[user_ops_first];

            // Traverse to next operation in queue.
            user_ops_first++;
            if (user_ops_first == p_user->user_op_queue_size)
            {
                user_ops_first = 0;
            }

            switch (p_user_op->op_type)
            {
                case TIMER_USER_OP_TYPE_STOP:
                    // Delete node if timer is running.
                    p_timer = p_user_op->p_node;
                    if (p_timer->is_running)
                    {
                        timer_list_remove(p_user_op->p_node);
                        p_timer->is_running = false;
                    }
                    break;
                    
                case TIMER_USER_OP_TYPE_STOP_ALL:
                    // Delete list of running timers, and mark all timers as not running.
                    while (mp_timer_id_head != NULL)
                    {
                        timer_node_t * p_head = mp_timer_id_head;

                        p_head->is_running = false;
                        mp_timer_id_head    = p_head->next;
                    }
                    break;
                    
                default:
                    // No implementation needed.
                    break;
            }
        }
    }

    // Detect change in head of the list.
    return (mp_timer_id_head != p_timer_old_head);
}
Exemple #6
0
void timer_set_global_time(attotime newbase)
{
	emu_timer *timer;

	/* set the new global offset */
	global_basetime = newbase;

	LOG(("timer_set_global_time: new=%s head->expire=%s\n", attotime_string(newbase, 9), attotime_string(timer_head->expire, 9)));

	/* now process any timers that are overdue */
	while (attotime_compare(timer_head->expire, global_basetime) <= 0)
	{
		int was_enabled = timer_head->enabled;

		/* if this is a one-shot timer, disable it now */
		timer = timer_head;
		if (attotime_compare(timer->period, attotime_zero) == 0 || attotime_compare(timer->period, attotime_never) == 0)
			timer->enabled = FALSE;

		/* set the global state of which callback we're in */
		callback_timer_modified = FALSE;
		callback_timer = timer;
		callback_timer_expire_time = timer->expire;

		/* call the callback */
		if (was_enabled && timer->callback != NULL)
		{
			LOG(("Timer %s:%d[%s] fired (expire=%s)\n", timer->file, timer->line, timer->func, attotime_string(timer->expire, 9)));
			profiler_mark(PROFILER_TIMER_CALLBACK);
			(*timer->callback)(Machine, timer->ptr, timer->param);
			profiler_mark(PROFILER_END);
		}

		/* clear the callback timer global */
		callback_timer = NULL;

		/* reset or remove the timer, but only if it wasn't modified during the callback */
		if (!callback_timer_modified)
		{
			/* if the timer is temporary, remove it now */
			if (timer->temporary)
				timer_remove(timer);

			/* otherwise, reschedule it */
			else
			{
				timer->start = timer->expire;
				timer->expire = attotime_add(timer->expire, timer->period);

				timer_list_remove(timer);
				timer_list_insert(timer);
			}
		}
	}
}
Exemple #7
0
void mame_timer_set_global_time(mame_time newbase)
{
	mame_timer *timer;

	/* set the new global offset */
	global_basetime = newbase;

	LOG(("mame_timer_set_global_time: new=%.9f head->expire=%.9f\n", mame_time_to_double(newbase), mame_time_to_double(timer_head->expire)));

	/* now process any timers that are overdue */
	while (compare_mame_times(timer_head->expire, global_basetime) <= 0)
	{
		int was_enabled = timer_head->enabled;

		/* if this is a one-shot timer, disable it now */
		timer = timer_head;
		if (compare_mame_times(timer->period, time_zero) == 0 || compare_mame_times(timer->period, time_never) == 0)
			timer->enabled = 0;

		/* set the global state of which callback we're in */
		callback_timer_modified = 0;
		callback_timer = timer;
		callback_timer_expire_time = timer->expire;

		/* call the callback */
		if (was_enabled && timer->callback)
		{
			LOG(("Timer %s:%d fired (expire=%.9f)\n", timer->file, timer->line, mame_time_to_double(timer->expire)));
			profiler_mark(PROFILER_TIMER_CALLBACK);
			(*timer->callback)(timer->callback_param);
			profiler_mark(PROFILER_END);
		}

		/* clear the callback timer global */
		callback_timer = NULL;

		/* reset or remove the timer, but only if it wasn't modified during the callback */
		if (!callback_timer_modified)
		{
			/* if the timer is temporary, remove it now */
			if (timer->temporary)
				timer_remove(timer);

			/* otherwise, reschedule it */
			else
			{
				timer->start = timer->expire;
				timer->expire = add_mame_times(timer->expire, timer->period);

				timer_list_remove(timer);
				timer_list_insert(timer);
			}
		}
	}
}
Exemple #8
0
int timer_enable(emu_timer *which, int enable)
{
	int old;

	/* set the enable flag */
	old = which->enabled;
	which->enabled = enable;

	/* remove the timer and insert back into the list */
	timer_list_remove(which);
	timer_list_insert(which);

	return old;
}
Exemple #9
0
static void timer_remove(emu_timer *which)
{
	/* if this is a callback timer, note that */
	if (which == callback_timer)
		callback_timer_modified = TRUE;

	/* remove it from the list */
	timer_list_remove(which);

	/* free it up by adding it back to the free list */
	if (timer_free_tail)
		timer_free_tail->next = which;
	else
		timer_free_head = which;
	which->next = NULL;
	timer_free_tail = which;
}
Exemple #10
0
RAW_OS_ERROR raw_timer_deactivate(RAW_TIMER *timer_ptr)
{
	RAW_OS_ERROR mutex_ret;
	
	#if (RAW_TIMER_FUNCTION_CHECK > 0)
	
	if (timer_ptr == 0) {
		return RAW_NULL_OBJECT;
	}

	if (raw_int_nesting) {

		return RAW_NOT_CALLED_BY_ISR;
		
	}
	
	#endif

	if (timer_ptr->object_type != RAW_TIMER_OBJ_TYPE) {

		return RAW_ERROR_OBJECT_TYPE;
	}
	
	/*Timer state TIMER_DEACTIVE  TIMER_DELETED is not allowed to delete*/
	if (timer_ptr->timer_state == TIMER_DEACTIVE) {
		return RAW_TIMER_STATE_INVALID;
	}
	
	if (timer_ptr->timer_state == TIMER_DELETED) {
		return RAW_TIMER_STATE_INVALID;

	}
	
	mutex_ret = raw_mutex_get(&timer_mutex, RAW_WAIT_FOREVER);
	RAW_ASSERT(mutex_ret == RAW_SUCCESS);
	
	timer_list_remove(timer_ptr);
	timer_ptr->timer_state = TIMER_DEACTIVE;
	raw_mutex_put(&timer_mutex);
	
	return RAW_SUCCESS;

}
Exemple #11
0
static void timer_remove(emu_timer *which)
{
	timer_private *global = which->machine->timer_data;

	/* if this is a callback timer, note that */
	if (which == global->callback_timer)
		global->callback_timer_modified = TRUE;

	/* remove it from the list */
	timer_list_remove(which);

	/* free it up by adding it back to the free list */
	if (global->freelist_tail)
		global->freelist_tail->next = which;
	else
		global->freelist = which;
	which->next = NULL;
	global->freelist_tail = which;
}
Exemple #12
0
void timer_remove(mame_timer *which)
{
	/* error if this is an inactive timer */
	if (which->tag == -1)
	{
		logerror("timer_remove: removed an inactive timer!\n");
		return;
	}

	/* remove it from the list */
	timer_list_remove(which);

	/* mark it as dead */
	which->tag = -1;

	/* free it up by adding it back to the free list */
	if (timer_free_tail)
		timer_free_tail->next = which;
	else
		timer_free_head = which;
	which->next = NULL;
	timer_free_tail = which;
}
Exemple #13
0
/*
************************************************************************************************************************
*                                    Timer task 
*
* Description: This function is called to  start a timer task.
*
* Arguments  :pa is the parameters to task.
*                    -----
*                
*				         
*				         
* Returns   
*				   
* Note(s) :This function is called by internal, users shoud not touch this function.
*
*             
************************************************************************************************************************
*/
void timer_task(void *pa) 
{
	LIST 								*timer_head_ptr;
	LIST 								*iter;
	LIST 								*iter_temp;
	RAW_TIMER							*timer_ptr;
	RAW_OS_ERROR                         mutex_ret;
	RAW_U16                              callback_ret;
	
	/*reset the timer_sem count since it may not be 0 at this point, make it start here*/
	raw_semaphore_set(&timer_sem, 0);
	pa = pa;
	
	while (1) {
		
		/*timer task will be blocked after call this function*/
		raw_semaphore_get(&timer_sem, RAW_WAIT_FOREVER);

		mutex_ret = raw_mutex_get(&timer_mutex, RAW_WAIT_FOREVER);
		RAW_ASSERT(mutex_ret == RAW_SUCCESS);

		/*calculate which  timer_head*/
		raw_timer_count++;                                          
	
		timer_head_ptr  = &timer_head;

		iter = timer_head_ptr->next;
		
		while (RAW_TRUE) {

			/*if timer exits*/	
			if (iter != timer_head_ptr) {

				/*Must use iter_temp because iter may be remove later.*/
				iter_temp = iter->next;
				timer_ptr =  raw_list_entry(iter, RAW_TIMER, timer_list);

				/*if timeout*/
				if (raw_timer_count == timer_ptr->match) {  

					/*remove from timer list*/
					timer_list_remove(timer_ptr);

					/*if timer is reschedulable*/			
					if (timer_ptr->reschedule_ticks) {

						/*Sort by remain time*/
						timer_ptr->remain = timer_ptr->reschedule_ticks;

						timer_ptr->match  = raw_timer_count + timer_ptr->remain;
						timer_ptr->to_head = &timer_head;
						timer_list_priority_insert(&timer_head, timer_ptr);
					          
					} 

					else {

						timer_ptr->timer_state = TIMER_DEACTIVE;

					}

					/*Any way both condition need to call registered timer function*/
					/*the registered timer function should not touch any timer related API,otherwise system will be crashed*/
					if (timer_ptr->raw_timeout_function) {

						callback_ret = timer_ptr->raw_timeout_function(timer_ptr->raw_timeout_param);
						if ((callback_ret == TIMER_CALLBACK_STOP) && (timer_ptr->timer_state != TIMER_DEACTIVE)) {
							/*remove from timer list*/
							timer_list_remove(timer_ptr);
							timer_ptr->timer_state = TIMER_DEACTIVE;
						}
					         
					}

					iter  = iter_temp; 

				} 

				else { 

					break;	
				}

			}

			/*exit because timer is not exit*/		
			else {

				break;
			}

		}

		raw_mutex_put(&timer_mutex);

	}


}
Exemple #14
0
void timer_execute_timers(running_machine *machine)
{
	timer_private *global = machine->timer_data;
	emu_timer *timer;

	/* if the current quantum has expired, find a new one */
	if (attotime_compare(global->exec.basetime, global->quantum_current->expire) >= 0)
	{
		int curr;

		global->quantum_current->requested = 0;
		global->quantum_current = &global->quantum_list[0];
		for (curr = 1; curr < ARRAY_LENGTH(global->quantum_list); curr++)
			if (global->quantum_list[curr].requested != 0 && global->quantum_list[curr].requested < global->quantum_current->requested)
				global->quantum_current = &global->quantum_list[curr];
		global->exec.curquantum = global->quantum_current->actual;
	}

	LOG(("timer_set_global_time: new=%s head->expire=%s\n", attotime_string(global->exec.basetime, 9), attotime_string(global->activelist->expire, 9)));

	/* now process any timers that are overdue */
	while (attotime_compare(global->activelist->expire, global->exec.basetime) <= 0)
	{
		int was_enabled = global->activelist->enabled;

		/* if this is a one-shot timer, disable it now */
		timer = global->activelist;
		if (attotime_compare(timer->period, attotime_zero) == 0 || attotime_compare(timer->period, attotime_never) == 0)
			timer->enabled = FALSE;

		/* set the global state of which callback we're in */
		global->callback_timer_modified = FALSE;
		global->callback_timer = timer;
		global->callback_timer_expire_time = timer->expire;

		/* call the callback */
		if (was_enabled && timer->callback != NULL)
		{
			LOG(("Timer %s:%d[%s] fired (expire=%s)\n", timer->file, timer->line, timer->func, attotime_string(timer->expire, 9)));
			profiler_mark_start(PROFILER_TIMER_CALLBACK);
			(*timer->callback)(machine, timer->ptr, timer->param);
			profiler_mark_end();
		}

		/* clear the callback timer global */
		global->callback_timer = NULL;

		/* reset or remove the timer, but only if it wasn't modified during the callback */
		if (!global->callback_timer_modified)
		{
			/* if the timer is temporary, remove it now */
			if (timer->temporary)
				timer_remove(timer);

			/* otherwise, reschedule it */
			else
			{
				timer->start = timer->expire;
				timer->expire = attotime_add(timer->expire, timer->period);

				timer_list_remove(timer);
				timer_list_insert(timer);
			}
		}
	}
}
Exemple #15
0
void timer_adjust_global_time(double delta)
{
	mame_timer *timer;

	/* add the delta to the global offset */
	global_offset += delta;

	/* scan the list and adjust the times */
	for (timer = timer_head; timer != NULL; timer = timer->next)
	{
		timer->start -= delta;
		timer->expire -= delta;
	}

	LOG(("timer_adjust_global_time: delta=%.9f head->expire=%.9f\n", delta, timer_head->expire));

	/* now process any timers that are overdue */
	while (timer_head->expire < TIME_IN_NSEC(1))
	{
		int was_enabled = timer_head->enabled;

		/* if this is a one-shot timer, disable it now */
		timer = timer_head;
		if (timer->period == 0)
			timer->enabled = 0;

		/* set the global state of which callback we're in */
		callback_timer_modified = 0;
		callback_timer = timer;
		callback_timer_expire_time = timer->expire;

		/* call the callback */
		if (was_enabled && timer->callback)
		{
			LOG(("Timer %08X fired (expire=%.9f)\n", (UINT32)timer, timer->expire));
			profiler_mark(PROFILER_TIMER_CALLBACK);
			(*timer->callback)(timer->callback_param);
			profiler_mark(PROFILER_END);
		}

		/* clear the callback timer global */
		callback_timer = NULL;

		/* reset or remove the timer, but only if it wasn't modified during the callback */
		if (!callback_timer_modified)
		{
			/* if the timer is temporary, remove it now */
			if (timer->temporary)
				timer_remove(timer);

			/* otherwise, reschedule it */
			else
			{
				timer->start = timer->expire;
				timer->expire += timer->period;

				timer_list_remove(timer);
				timer_list_insert(timer);
			}
		}
	}
}