Esempio n. 1
0
bool VM::check_interrupts(CallFrame* call_frame, void* end) {
    // First, we might be here because someone reset the stack_limit_ so that
    // we'd fall into here to check interrupts even if the stack is fine,
    //
    // So fix up the stack_limit_ if thats the case first.

    // If this is true, stack_limit_ was just changed to get our attention, reset
    // it now.
    if(stack_limit_ == stack_start_) {
        reset_stack_limit();
    } else {
        if(!check_stack(call_frame, end)) return false;
    }

    if(unlikely(check_local_interrupts)) {
        if(!process_async(call_frame)) return false;
    }

    // If the current thread is trying to step, debugger wise, then assist!
    if(thread_step()) {
        clear_thread_step();
        if(!Helpers::yield_debugger(this, call_frame, Qnil)) return false;
    }

    return true;
}
Esempio n. 2
0
 bool check_async(CallFrame* call_frame) {
   if(check_local_interrupts) {
     return process_async(call_frame);
   }
   return true;
 }
Esempio n. 3
0
static void *swd_reader(void *arg) {
	uint32_t data[MAXWORDS];
	unsigned query_id;
	int r;
	int once = 1;
restart:
	for (;;) {
		if ((usb = usb_open(0x18d1, 0xdb03, 0))) break;
		if ((usb = usb_open(0x18d1, 0xdb04, 0))) break;
		if (once) {
			xprintf(XSWD, "usb: waiting for debugger device\n");
			once = 0;
		}
		usleep(250000);
	}
	once = 0;
	xprintf(XSWD, "usb: debugger connected\n");

	pthread_mutex_lock(&swd_lock);

	// send a version query to find out about the firmware
	// old m3debug fw will just report failure
 	query_id = sequence++;
	query_id = RSWD_TXN_START(query_id);
	data[0] = query_id;
	data[1] = RSWD_MSG(CMD_VERSION, 0, RSWD_VERSION);
	usb_write(usb, data, 8);
	for (;;) {
		pthread_mutex_unlock(&swd_lock);
		r = usb_read_forever(usb, data, MAXWORDS * 4);
		pthread_mutex_lock(&swd_lock);
		if (r < 0) {
			xprintf(XSWD, "usb: debugger disconnected\n");
			swd_online = -1;
			swd_txn_status = TXN_STATUS_FAIL;
			pthread_cond_broadcast(&swd_event);
			break;
		}
		if ((r < 4) || (r & 3)) {
			xprintf(XSWD, "usb: discard packet (%d)\n", r);
			continue;
		}
		if (query_id && (data[0] == query_id)) {
			query_id = 0;
			process_query(data + 1, (r / 4) - 1);
			swd_online = 1;
		} else if (data[0] == RSWD_TXN_ASYNC) {
			pthread_mutex_unlock(&swd_lock);
			process_async(data + 1, (r / 4) - 1);
			pthread_mutex_lock(&swd_lock);
		} else if ((swd_txn_status == TXN_STATUS_WAIT) &&
			(data[0] == swd_txn_id)) {
			swd_txn_status = r;
			memcpy(swd_txn_data, data, r);
			pthread_cond_broadcast(&swd_event);
		} else {
			xprintf(XSWD, "usb: rx: unexpected txn %08x (%d)\n", data[0], r);
		}
	}
	// wait for a reader to ack the shutdown (and close usb)
	while (swd_online == -1) {
		pthread_cond_wait(&swd_event, &swd_lock);
	}
	pthread_mutex_unlock(&swd_lock);
	usleep(250000);
	goto restart;
	return NULL;
}
Esempio n. 4
0
int ape_timers_process(ape_global *ape_ctx)
{
    ape_timers *timers = &ape_ctx->timersng;

    ape_timer_t *cur = timers->head;
    uint64_t inums = UINT64_MAX, lastsample = 0;

    process_async(timers);

    /* TODO: paused timer */
    while (cur != NULL) {
        uint64_t start;

        if (cur->flags & APE_TIMER_IS_CLEARED) {
            cur = ape_timer_destroy(timers, cur);
            continue;
        }

        if ((start = mach_absolute_time()) >= cur->schedule - 150000) {
            uint64_t ret;
            unsigned int duration;

            ret = cur->callback(cur->arg);

            // printf("Timer returned %lld\n", ret);

            if (ret == -1) {
                cur->schedule = start + cur->ticks_needs;
            } else if (ret == 0) {
                cur = ape_timer_destroy(timers, cur);
                continue;
            } else {
                cur->ticks_needs = ret * 1000000;
                cur->schedule    = start + cur->ticks_needs;
            }

            lastsample = mach_absolute_time();
            duration   = lastsample - start;

            if (cur->stats.max < duration / 1000000) {
                cur->stats.max = duration / 1000000;
            }
            if (cur->stats.min == 0 || duration / 1000000 < cur->stats.min) {
                cur->stats.min = duration / 1000000;
            }
            cur->stats.nexec++;
            cur->stats.totaltime += duration / 1000000;
        }

        if (cur->schedule < inums) {
            inums = cur->schedule;
        }

        cur = cur->next;
    }

    process_async(timers);

    if (inums == UINT64_MAX) {
        return APE_TIMER_RESOLUTION;
    }

    if (lastsample == 0) {
        lastsample = mach_absolute_time();
    }

    // printf("Next timer in : %lld or %d\n", inums-lastsample,  ape_max(1,
    // (int)((inums-lastsample+500000)/1000000)));

    return ape_max((timers->run_in_low_resolution ? 100 : 1),
                   (int)((inums - lastsample + 500000) / 1000000));
}