⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hal13c1-2.4.25.patch

📁 rtai-3.1-test3的源代码(Real-Time Application Interface )
💻 PATCH
📖 第 1 页 / 共 5 页
字号:
++    for (event = 0; event < ADEOS_NR_EVENTS; event++)+	/* Need this to update the monitor count. */+	adeos_catch_event(event,NULL);++#ifdef CONFIG_SMP+    {+    unsigned irq;+    int _cpuid;++    /* In the SMP case, wait for the logged events to drain on other+       processors before eventually removing the domain from the+       pipeline. */++    adeos_unstall_pipeline_from(adp);++    flags = adeos_critical_enter(NULL);++    for (irq = 0; irq < IPIPE_NR_IRQS; irq++)+	{+	clear_bit(IPIPE_HANDLE_FLAG,&adp->irqs[irq].control);+	clear_bit(IPIPE_STICKY_FLAG,&adp->irqs[irq].control);+	set_bit(IPIPE_PASS_FLAG,&adp->irqs[irq].control);+	}++    adeos_critical_exit(flags);++    for (_cpuid = 0; _cpuid < smp_num_cpus; _cpuid++)+	{+	for (irq = 0; irq < IPIPE_NR_IRQS; irq++)+	    while (adp->cpudata[_cpuid].irq_hits[irq] > 0)+		cpu_relax();++	while (test_bit(IPIPE_XPEND_FLAG,&adp->cpudata[_cpuid].status))+	    cpu_relax();++	while (!test_bit(IPIPE_SLEEP_FLAG,&adp->cpudata[_cpuid].status))+	     cpu_relax();+	}+    }+#endif /* CONFIG_SMP */++    /* Simply remove the domain from the pipeline and we are almost+       done. */++    flags = adeos_critical_enter(NULL);+    list_del_init(&adp->p_link);+    adeos_critical_exit(flags);++    __adeos_cleanup_domain(adp);++    printk(KERN_WARNING "Adeos: Domain %s unregistered.\n",adp->name);++    return 0;+}++/* adeos_renice_domain() -- Change the priority of the current+   domain. This affects the position of the domain in the interrupt+   pipeline. The greater the priority value, the earlier the domain is+   informed of incoming events when the pipeline is processed. This+   routine causes a round-robin effect if newpri == oldpri. */++void adeos_renice_domain (int newpri)++{+    adomain_t *adp, *nadp = NULL;+    unsigned long lflags, xflags;+    struct list_head *pos;+    adeos_declare_cpuid;++    /* We do want adeos_critical_exit() to leave the IRQs masked, so+       we first clear the interrupt bit before calling+       adeos_critical_enter(). */+ +    adeos_lock_cpu(lflags);++    adp = adp_cpu_current[cpuid];++    xflags = adeos_critical_enter(NULL);++    list_del_init(&adp->p_link);++    list_for_each(pos,&__adeos_pipeline) {+    	adomain_t *_adp = list_entry(pos,adomain_t,p_link);++	if (newpri > _adp->priority)+            break;++	/* While scanning the pipeline from its head to the current+	   domain's new position, pick the first domain which is+	   entitled to preempt us. Such domain must be either:+	   o in a preempted state (i.e. !sleeping),+	   o or sleeping and unstalled with events to process. */++	if (nadp == NULL &&+	    (!test_bit(IPIPE_SLEEP_FLAG,&_adp->cpudata[cpuid].status) ||+	     (!test_bit(IPIPE_STALL_FLAG,&_adp->cpudata[cpuid].status) &&+	      _adp->cpudata[cpuid].irq_pending_hi != 0) ||+	     test_bit(IPIPE_XPEND_FLAG,&_adp->cpudata[cpuid].status)))+	    nadp = _adp;+    }++    list_add_tail(&adp->p_link,pos);+    adp->priority = newpri;+    +    /* On SMP systems, we release the other CPUs but we still keep the+       local IRQs masked so that we can't jump to a stale domain. */++    adeos_critical_exit(xflags);++    if (nadp == NULL)+	goto release_cpu_and_exit;++    __adeos_switch_to(nadp,cpuid);++    adeos_load_cpuid(); /* Processor might have changed. */++    /* Try sync'ing pending interrupts on return from our preemption+       point. */++    if (!test_bit(IPIPE_STALL_FLAG,&adp_cpu_current[cpuid]->cpudata[cpuid].status) &&+	adp_cpu_current[cpuid]->cpudata[cpuid].irq_pending_hi != 0)+	__adeos_sync_stage(IPIPE_IRQMASK_ANY);++    /* Note that we only need to sync interrupts here, since other+       kind of events (i.e. synchronous ones) cannot flow across the+       domain which triggers them down the pipeline. Since a more+       prioritary domain was running up to now, there is no chance for+       us to have such event pending. */++release_cpu_and_exit:++    adeos_unlock_cpu(lflags);+}++int __adeos_schedule_irq (unsigned irq, struct list_head *head)++{+    struct list_head *ln;+    unsigned long flags;+    adeos_declare_cpuid;++    if (irq >= IPIPE_NR_IRQS ||+	(adeos_virtual_irq_p(irq) && !test_bit(irq - IPIPE_VIRQ_BASE,&__adeos_virtual_irq_map)))+	return -EINVAL;++    adeos_lock_cpu(flags);++    ln = head;++    while (ln != &__adeos_pipeline)+	{+	adomain_t *adp = list_entry(ln,adomain_t,p_link);++	if (test_bit(IPIPE_HANDLE_FLAG,&adp->irqs[irq].control))+	    {+	    adp->cpudata[cpuid].irq_hits[irq]++;+	    __adeos_set_irq_bit(adp,cpuid,irq);+	    adeos_unlock_cpu(flags);+	    return 1;+	    }++	ln = adp->p_link.next;+	}++    adeos_unlock_cpu(flags);++    return 0;+}++/* adeos_propagate_irq() -- Force a given IRQ propagation on behalf of+   a running interrupt handler to the next domain down the pipeline.+   Returns non-zero if a domain has received the interrupt+   notification, zero otherwise.+   This call is useful for handling shared interrupts among domains.+   e.g. pipeline = [domain-A]---[domain-B]...+   Both domains share IRQ #X.+   - domain-A handles IRQ #X but does not pass it down (i.e. Terminate+   or Dynamic interrupt control mode)+   - domain-B handles IRQ #X (i.e. Terminate or Accept interrupt+   control modes).+   When IRQ #X is raised, domain-A's handler determines whether it+   should process the interrupt by identifying its source. If not,+   adeos_propagate_irq() is called so that the next domain down the+   pipeline which handles IRQ #X is given a chance to process it. This+   process can be repeated until the end of the pipeline is+   reached. */++int adeos_propagate_irq (unsigned irq) {++    return __adeos_schedule_irq(irq,adp_current->p_link.next);+}++/* adeos_schedule_irq() -- Almost the same as adeos_propagate_irq(),+   but attempts to pend the interrupt for the current domain first. */++int adeos_schedule_irq (unsigned irq) {++    return __adeos_schedule_irq(irq,&adp_current->p_link);+}++unsigned long adeos_set_irq_affinity (unsigned irq, unsigned long cpumask)++{+#ifdef CONFIG_SMP+     if (irq >= IPIPE_NR_XIRQS)+	 /* Allow changing affinity of external IRQs only. */+	 return 0;++     if (smp_num_cpus > 1)+	 /* Allow changing affinity of external IRQs only. */+	 return __adeos_set_irq_affinity(irq,cpumask);+#endif /* CONFIG_SMP */++    return 0;+}++/* adeos_free_irq() -- Return a previously allocated virtual/soft+   pipelined interrupt to the pool of allocatable interrupts. */++int adeos_free_irq (unsigned irq)++{+    if (irq >= IPIPE_NR_IRQS)+	return -EINVAL;++    clear_bit(irq - IPIPE_VIRQ_BASE,&__adeos_virtual_irq_map);++    return 0;+}++/* adeos_unstall_pipeline_from() -- Unstall the interrupt pipeline and+   synchronize pending events from a given domain. */++void adeos_unstall_pipeline_from (adomain_t *adp)++{+    struct list_head *pos;+    unsigned long flags;+    adeos_declare_cpuid;++    adeos_get_cpu(flags);++    clear_bit(IPIPE_STALL_FLAG,&adp->cpudata[cpuid].status);++    if (adp == adp_cpu_current[cpuid])+	{+	if (adp->cpudata[cpuid].irq_pending_hi != 0)+	    __adeos_sync_stage(IPIPE_IRQMASK_ANY);++	goto release_cpu_and_exit;+	}++    /* Attempt to flush all events that might be pending at the+       unstalled domain level. This code is roughly lifted from+       drivers/adeos/x86.c:__adeos_walk_pipeline(). */++    list_for_each(pos,&__adeos_pipeline) {++    	adomain_t *_adp = list_entry(pos,adomain_t,p_link);++	if (test_bit(IPIPE_STALL_FLAG,&_adp->cpudata[cpuid].status))+	    break; /* Stalled stage -- do not go further. */++	if (_adp->cpudata[cpuid].irq_pending_hi != 0)+	    {+	    /* Since the critical IPI might be triggered by the+	       following actions, the current domain might not be+	       linked to the pipeline anymore after its handler+	       returns on SMP boxen, even if the domain remains valid+	       (see adeos_unregister_domain()), so don't make any+	       hazardous assumptions here. */++	    if (_adp == adp_cpu_current[cpuid])+		__adeos_sync_stage(IPIPE_IRQMASK_ANY);+	    else+		{+		__adeos_switch_to(_adp,cpuid);++		adeos_load_cpuid(); /* Processor might have changed. */++		if (!test_bit(IPIPE_STALL_FLAG,&adp_cpu_current[cpuid]->cpudata[cpuid].status) &&+		    adp_cpu_current[cpuid]->cpudata[cpuid].irq_pending_hi != 0)+		    __adeos_sync_stage(IPIPE_IRQMASK_ANY);+		}+	    +	    break;+	    }+	else if (_adp == adp_cpu_current[cpuid])+	    break;+    }++release_cpu_and_exit:++    adeos_put_cpu(flags);+}++/* adeos_catch_event_from() -- Interpose an event handler starting+   from a given domain. */++int adeos_catch_event_from (adomain_t *adp, unsigned event, void (*handler)(adevinfo_t *))++{+    if (event >= ADEOS_NR_EVENTS)+	return -EINVAL;++    if (!xchg(&adp->events[event].handler,handler))+	{+	if (handler)+	    __adeos_event_monitors[event]++;+	}+    else if (!handler)+	__adeos_event_monitors[event]--;++    return 0;+}++void (*adeos_hook_dswitch(void (*handler)(void))) (void) {++    return (void (*)(void))xchg(&adp_current->dswitch,handler);+}++void adeos_init_attr (adattr_t *attr)++{+    attr->name = "Anonymous";+    attr->domid = 1;+    attr->entry = NULL;+    attr->estacksz = 0;	/* Let ADEOS choose a reasonable stack size */+    attr->priority = ADEOS_ROOT_PRI;+    attr->dswitch = NULL;+    attr->nptdkeys = 0;+    attr->ptdset = NULL;+    attr->ptdget = NULL;+}++int adeos_alloc_ptdkey (void)++{+    unsigned long flags;+    int key = -1;++    adeos_spin_lock_irqsave(&__adeos_pipelock,flags);++    if (adp_current->ptd_keycount < adp_current->ptd_keymax)+	{+	key = ffz(adp_current->ptd_keymap);+	set_bit(key,&adp_current->ptd_keymap);+	adp_current->ptd_keycount++;+	}++    adeos_spin_unlock_irqrestore(&__adeos_pipelock,flags);++    return key;+}++int adeos_free_ptdkey (int key)++{+    unsigned long flags; ++    if (key < 0 || key >= adp_current->ptd_keymax)+	return -EINVAL;++    adeos_spin_lock_irqsave(&__adeos_pipelock,flags);++    if (test_and_clear_bit(key,&adp_current->ptd_keymap))+	adp_current->ptd_keycount--;++    adeos_spin_unlock_irqrestore(&__adeos_pipelock,flags);++    return 0;+}++int adeos_set_ptd (int key, void *value)++{+    if (key < 0 || key >= adp_current->ptd_keymax)+	return -EINVAL;++    if (!adp_current->ptd_setfun)+	{+	printk(KERN_WARNING "Adeos: No ptdset hook for %s\n",adp_current->name);+	return -EINVAL;+	}++    adp_current->ptd_setfun(key,value);++    return 0;+}++void *adeos_get_ptd (int key)++{+    if (key < 0 || key >= adp_current->ptd_keymax)+	return NULL;++    if (!adp_current->ptd_getfun)+	{+	printk(KERN_WARNING "Adeos: No ptdget hook for %s\n",adp_current->name);+	return NULL;+	}++    return adp_current->ptd_getfun(key);+}++int adeos_init_mutex (admutex_t *mutex)++{+    admutex_t initm = ADEOS_MUTEX_UNLOCKED;+    *mutex = initm;+    return 0;+}++int adeos_destroy_mutex (admutex_t *mutex)++{+    if (!adeos_spin_trylock(&mutex->lock) &&+	adp_current != adp_root &&+	mutex->owner != adp_current)+	return -EBUSY;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -