diff options
author | Christopher Kenna <cjk@cs.unc.edu> | 2011-09-30 01:23:20 -0400 |
---|---|---|
committer | Christopher Kenna <cjk@cs.unc.edu> | 2011-09-30 01:23:20 -0400 |
commit | cd5685b6483df2f1ba8affc0ff8a0679f4044db8 (patch) | |
tree | b2c15c6f04fdfd96a738900d8e822057847ea641 /include | |
parent | 23a00b911b968c6290251913ecc34171836b4d32 (diff) |
Refactor timer merging and add it to CE plugin.
THIS CODE IS UNTESTED
We now initialize one event group for each cpu on system start. We can
get the event group for a CPU via a function in event_group.c
Another change is that an event now stores what group it is in when it
add_event() is called on it. This lets us cancel it without knowing what
event group it is in.
The above is important because Level-C events (like releases) have a
NULL event group. When calling add_event(), it will get the event group
of the current CPU. If the event needs to be canceled later, we need
that saved group in the event so we know where to remove it from.
Diffstat (limited to 'include')
-rw-r--r-- | include/litmus/ce_domain.h | 4 | ||||
-rw-r--r-- | include/litmus/event_group.h | 26 | ||||
-rw-r--r-- | include/litmus/sched_mc.h | 13 |
3 files changed, 27 insertions, 16 deletions
diff --git a/include/litmus/ce_domain.h b/include/litmus/ce_domain.h index 373f3f5f78d3..5d5fdf7d1efc 100644 --- a/include/litmus/ce_domain.h +++ b/include/litmus/ce_domain.h | |||
@@ -8,7 +8,11 @@ void ce_requeue(domain_t*, struct task_struct*); | |||
8 | struct task_struct* ce_peek_and_take_ready(domain_t*); | 8 | struct task_struct* ce_peek_and_take_ready(domain_t*); |
9 | int ce_higher_prio(struct task_struct*, struct task_struct*); | 9 | int ce_higher_prio(struct task_struct*, struct task_struct*); |
10 | 10 | ||
11 | #ifdef CONFIG_MERGE_TIMERS | ||
12 | typedef void (*ce_timer_callback_t)(struct rt_event*); | ||
13 | #else | ||
11 | typedef enum hrtimer_restart (*ce_timer_callback_t)(struct hrtimer*); | 14 | typedef enum hrtimer_restart (*ce_timer_callback_t)(struct hrtimer*); |
15 | #endif | ||
12 | 16 | ||
13 | void ce_domain_init(domain_t*, | 17 | void ce_domain_init(domain_t*, |
14 | raw_spinlock_t*, | 18 | raw_spinlock_t*, |
diff --git a/include/litmus/event_group.h b/include/litmus/event_group.h index a2e4d4507738..51d9a0a51e85 100644 --- a/include/litmus/event_group.h +++ b/include/litmus/event_group.h | |||
@@ -45,19 +45,18 @@ struct rt_event { | |||
45 | * events. | 45 | * events. |
46 | */ | 46 | */ |
47 | struct event_list *event_list; | 47 | struct event_list *event_list; |
48 | }; | ||
49 | 48 | ||
50 | /** | 49 | /* |
51 | * init_event_group() - Prepare group for events. | 50 | * Pointer set by add_event() so that we can cancel this event |
52 | * @group Group to prepare | 51 | * without knowing what group it is in (don't touch it). |
53 | * @res Timer resolution. Two events of @res distance will be merged | 52 | */ |
54 | * @cpu Cpu on which to fire timers | 53 | struct event_group *_event_group; |
55 | */ | 54 | }; |
56 | void init_event_group(struct event_group* group, lt_t res, int cpu); | ||
57 | 55 | ||
58 | /** | 56 | /** |
59 | * add_event() - Add timer to event group. | 57 | * add_event() - Add timer to event group. |
60 | * @group Group with which to merge event | 58 | * @group Group with which to merge event. If NULL, use the event |
59 | * group of whatever CPU currently executing on. | ||
61 | * @e Event to be fired at a specific time | 60 | * @e Event to be fired at a specific time |
62 | * @time Time to fire event | 61 | * @time Time to fire event |
63 | */ | 62 | */ |
@@ -66,7 +65,7 @@ void add_event(struct event_group* group, struct rt_event* e, lt_t time); | |||
66 | /** | 65 | /** |
67 | * cancel_event() - Remove event from the group. | 66 | * cancel_event() - Remove event from the group. |
68 | */ | 67 | */ |
69 | void cancel_event(struct event_group *group, struct rt_event*); | 68 | void cancel_event(struct rt_event*); |
70 | 69 | ||
71 | /** | 70 | /** |
72 | * init_event() - Create an event. | 71 | * init_event() - Create an event. |
@@ -81,4 +80,11 @@ void init_event(struct rt_event* e, int prio, fire_event_t function, | |||
81 | struct event_list* event_list_alloc(int); | 80 | struct event_list* event_list_alloc(int); |
82 | void event_list_free(struct event_list *el); | 81 | void event_list_free(struct event_list *el); |
83 | 82 | ||
83 | /** | ||
84 | * get_event_group_for() - Get the event group for a CPU. | ||
85 | * @cpu The CPU to get the event group for. Use NO_CPU to get the | ||
86 | * event group of the CPU that the call is executing on. | ||
87 | */ | ||
88 | struct event_group *get_event_group_for(const int cpu); | ||
89 | |||
84 | #endif | 90 | #endif |
diff --git a/include/litmus/sched_mc.h b/include/litmus/sched_mc.h index 95cc367c8ade..7088c0766db2 100644 --- a/include/litmus/sched_mc.h +++ b/include/litmus/sched_mc.h | |||
@@ -51,12 +51,12 @@ struct mc_data { | |||
51 | struct ce_dom_data { | 51 | struct ce_dom_data { |
52 | int cpu; | 52 | int cpu; |
53 | struct task_struct *scheduled, *should_schedule; | 53 | struct task_struct *scheduled, *should_schedule; |
54 | /* | 54 | #ifdef CONFIG_MERGE_TIMERS |
55 | * Each CPU needs a mapping of level A ID (integer) to struct pid so | 55 | struct rt_event event; |
56 | * that we can get its task struct. | 56 | #else |
57 | */ | ||
58 | struct hrtimer_start_on_info timer_info; | 57 | struct hrtimer_start_on_info timer_info; |
59 | struct hrtimer timer; | 58 | struct hrtimer timer; |
59 | #endif | ||
60 | }; | 60 | }; |
61 | 61 | ||
62 | /** | 62 | /** |
@@ -65,7 +65,8 @@ struct ce_dom_data { | |||
65 | * @linked Logically running task, ghost or regular | 65 | * @linked Logically running task, ghost or regular |
66 | * @domain Domain from which to draw tasks | 66 | * @domain Domain from which to draw tasks |
67 | * @usable False if a higher criticality task is running | 67 | * @usable False if a higher criticality task is running |
68 | * @timer For ghost task budget enforcement | 68 | * @event For ghost task budget enforcement (merge timers) |
69 | * @timer For ghost task budget enforcement (not merge timers) | ||
69 | * @node Used to sort crit_entries by preemptability in global domains | 70 | * @node Used to sort crit_entries by preemptability in global domains |
70 | */ | 71 | */ |
71 | struct crit_entry { | 72 | struct crit_entry { |
@@ -105,7 +106,7 @@ unsigned int mc_ce_get_expected_job(const int, const int); | |||
105 | */ | 106 | */ |
106 | long mc_ce_admit_task_common(struct task_struct*); | 107 | long mc_ce_admit_task_common(struct task_struct*); |
107 | void mc_ce_task_exit_common(struct task_struct*); | 108 | void mc_ce_task_exit_common(struct task_struct*); |
108 | void mc_ce_timer_callback_common(domain_t*, struct hrtimer*); | 109 | lt_t mc_ce_timer_callback_common(domain_t*); |
109 | void mc_ce_release_at_common(struct task_struct*, lt_t); | 110 | void mc_ce_release_at_common(struct task_struct*, lt_t); |
110 | long mc_ce_activate_plugin_common(void); | 111 | long mc_ce_activate_plugin_common(void); |
111 | long mc_ce_deactivate_plugin_common(void); | 112 | long mc_ce_deactivate_plugin_common(void); |