Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
SWIFT
SWIFTsim
Commits
e54b2d82
Commit
e54b2d82
authored
Oct 20, 2012
by
Pedro Gonnet
Browse files
add biased task selection.
Former-commit-id: f227d3fda832ff4b0f0da54d44612bdfa88eaa97
parent
74221955
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/cell.h
View file @
e54b2d82
...
...
@@ -73,6 +73,9 @@ struct cell {
/* Spin lock for various uses. */
lock_type
lock
;
/* ID of the previous owner, e.g. runner. */
int
owner
;
/* Linking pointer for "memory management". */
struct
cell
*
next
;
...
...
src/queue.c
View file @
e54b2d82
...
...
@@ -84,6 +84,34 @@ int queue_counter[ queue_counter_count ];
/**
* @brief Insert a used tasks into the given queue.
*
* @param q The #queue.
* @param t The #task.
*/
void
queue_insert
(
struct
queue
*
q
,
struct
task
*
t
)
{
int
k
;
/* Lock the queue. */
if
(
lock_lock
(
&
q
->
lock
)
!=
0
)
error
(
"Failed to get queue lock."
);
/* Bubble-up the tasks. */
for
(
k
=
q
->
count
;
k
>
q
->
next
;
k
--
)
q
->
tid
[
k
]
=
q
->
tid
[
k
-
1
];
q
->
tid
[
q
->
next
]
=
t
-
q
->
tasks
;
q
->
count
+=
1
;
q
->
next
+=
1
;
/* Unlock the queue. */
if
(
lock_unlock
(
&
q
->
lock
)
!=
0
)
error
(
"Failed to unlock queue."
);
}
/**
* @brief Initialize the given queue.
*
...
...
@@ -239,6 +267,152 @@ struct task *queue_gettask ( struct queue *q , int blocking , int keep ) {
}
struct
task
*
queue_gettask_new
(
struct
queue
*
q
,
int
rid
,
int
blocking
,
int
keep
)
{
int
k
,
tid
=
-
1
,
qcount
,
*
qtid
=
q
->
tid
;
lock_type
*
qlock
=
&
q
->
lock
;
struct
task
*
qtasks
=
q
->
tasks
,
*
res
=
NULL
;
int
ind_best
,
score_best
=
-
1
,
score
;
TIMER_TIC
/* If there are no tasks, leave immediately. */
if
(
q
->
next
>=
q
->
count
)
{
TIMER_TOC
(
queue_timer_gettask
);
return
NULL
;
}
/* Main loop, while there are tasks... */
while
(
q
->
next
<
q
->
count
)
{
/* Grab the task lock. */
// if ( blocking ) {
if
(
lock_lock
(
qlock
)
!=
0
)
error
(
"Locking the task_lock failed.
\n
"
);
// }
// else {
// if ( lock_trylock( qlock ) != 0 )
// break;
// }
/* Loop over the remaining task IDs. */
qcount
=
q
->
count
;
ind_best
=
-
1
;
for
(
k
=
q
->
next
;
k
<
qcount
;
k
++
)
{
/* Put a finger on the task. */
res
=
&
qtasks
[
qtid
[
k
]
];
/* Is this task blocked? */
if
(
res
->
wait
)
continue
;
/* Get the score for this task. */
if
(
res
->
type
==
tid_self
||
res
->
type
==
tid_sort
||
(
res
->
type
==
tid_sub
&&
res
->
cj
==
NULL
)
)
score
=
(
res
->
ci
->
owner
==
rid
);
else
score
=
(
res
->
ci
->
owner
==
rid
)
+
(
res
->
cj
->
owner
==
rid
);
if
(
score
<=
score_best
)
continue
;
/* Different criteria for different types. */
if
(
res
->
type
==
tid_self
||
(
res
->
type
==
tid_sub
&&
res
->
cj
==
NULL
)
)
{
if
(
res
->
ci
->
hold
||
cell_locktree
(
res
->
ci
)
!=
0
)
continue
;
}
else
if
(
res
->
type
==
tid_pair
||
(
res
->
type
==
tid_sub
&&
res
->
cj
!=
NULL
)
)
{
if
(
res
->
ci
->
hold
||
res
->
cj
->
hold
||
res
->
ci
->
wait
||
res
->
cj
->
wait
)
continue
;
if
(
cell_locktree
(
res
->
ci
)
!=
0
)
continue
;
if
(
cell_locktree
(
res
->
cj
)
!=
0
)
{
cell_unlocktree
(
res
->
ci
);
continue
;
}
}
/* If we owned a previous task, unlock it. */
if
(
ind_best
>=
0
)
{
res
=
&
qtasks
[
qtid
[
ind_best
]
];
if
(
res
->
type
==
tid_self
||
res
->
type
==
tid_pair
||
res
->
type
==
tid_sub
)
cell_unlocktree
(
res
->
ci
);
if
(
res
->
type
==
tid_pair
||
(
res
->
type
==
tid_sub
&&
res
->
cj
!=
NULL
)
)
cell_unlocktree
(
res
->
cj
);
}
/* If we made it this far, we're safe. */
ind_best
=
k
;
score_best
=
score
;
/* Should we bother looking any farther? */
if
(
score_best
==
2
)
break
;
}
/* loop over the task IDs. */
/* Did we get a task? */
if
(
ind_best
>=
0
)
{
/* Do we need to swap? */
if
(
ind_best
!=
q
->
next
)
COUNT
(
queue_counter_swap
);
/* get the task ID. */
tid
=
qtid
[
ind_best
];
/* Own the cells involved. */
qtasks
[
tid
].
ci
->
owner
=
rid
;
if
(
qtasks
[
tid
].
cj
!=
NULL
)
qtasks
[
tid
].
cj
->
owner
=
rid
;
/* Remove the task? */
if
(
keep
)
{
/* Bubble-up. */
q
->
count
=
qcount
-
1
;
for
(
k
=
ind_best
;
k
<
qcount
-
1
;
k
++
)
qtid
[
k
]
=
qtid
[
k
+
1
];
}
/* No, leave it in the queue. */
else
{
TIMER_TIC2
/* Bubble-down the task. */
for
(
k
=
ind_best
;
k
>
q
->
next
;
k
--
)
qtid
[
k
]
=
qtid
[
k
-
1
];
qtid
[
q
->
next
]
=
tid
;
/* up the counter. */
q
->
next
+=
1
;
TIMER_TOC2
(
queue_timer_bubble
);
}
}
/* Release the task lock. */
if
(
lock_unlock
(
qlock
)
!=
0
)
error
(
"Unlocking the task_lock failed.
\n
"
);
/* Leave? */
if
(
tid
>=
0
)
{
TIMER_TOC
(
queue_timer_gettask
);
return
&
qtasks
[
tid
];
}
else
if
(
!
blocking
)
break
;
}
/* while there are tasks. */
/* No beef. */
TIMER_TOC
(
queue_timer_gettask
);
return
NULL
;
}
/**
* @brief Sort the tasks IDs according to their weight and constraints.
*
...
...
src/queue.h
View file @
e54b2d82
...
...
@@ -56,5 +56,7 @@ struct queue {
/* Function prototypes. */
struct
task
*
queue_gettask
(
struct
queue
*
q
,
int
blocking
,
int
keep
);
struct
task
*
queue_gettask_new
(
struct
queue
*
q
,
int
rid
,
int
blocking
,
int
keep
);
void
queue_init
(
struct
queue
*
q
,
int
size
,
struct
task
*
tasks
);
void
queue_insert
(
struct
queue
*
q
,
struct
task
*
t
);
void
queue_sort
(
struct
queue
*
q
);
src/runner.c
View file @
e54b2d82
...
...
@@ -1030,7 +1030,6 @@ void *runner_main ( void *data ) {
struct
runner_thread
*
rt
=
(
struct
runner_thread
*
)
data
;
struct
runner
*
r
=
rt
->
r
;
struct
space
*
s
=
r
->
s
;
int
threadID
=
rt
->
id
;
int
k
,
qid
,
naq
,
keep
,
tpq
;
struct
queue
*
queues
[
r
->
nr_queues
],
*
myq
;
...
...
@@ -1080,11 +1079,11 @@ void *runner_main ( void *data ) {
TIMER_TIC
t
=
NULL
;
if
(
r
->
nr_queues
==
1
)
{
t
=
queue_gettask
(
&
r
->
queues
[
0
]
,
1
,
0
);
t
=
queue_gettask
_new
(
&
r
->
queues
[
0
]
,
rt
->
id
,
1
,
0
);
}
else
if
(
r
->
policy
&
runner_policy_steal
)
{
if
(
(
myq
->
next
==
myq
->
count
)
||
(
t
=
queue_gettask
(
myq
,
0
,
0
)
)
==
NULL
)
{
(
t
=
queue_gettask
_new
(
myq
,
rt
->
id
,
0
,
0
)
)
==
NULL
)
{
TIMER_TIC2
qid
=
rand_r
(
&
myseed
)
%
naq
;
keep
=
(
r
->
policy
&
runner_policy_keep
)
&&
...
...
@@ -1093,19 +1092,9 @@ void *runner_main ( void *data ) {
COUNT
(
runner_counter_steal_empty
);
else
COUNT
(
runner_counter_steal_stall
);
t
=
queue_gettask
(
queues
[
qid
]
,
0
,
keep
);
if
(
t
!=
NULL
&&
keep
)
{
COUNT
(
runner_counter_keep
);
if
(
lock_lock
(
&
myq
->
lock
)
!=
0
)
error
(
"Failed to get queue lock."
);
for
(
k
=
myq
->
count
;
k
>
myq
->
next
;
k
--
)
myq
->
tid
[
k
]
=
myq
->
tid
[
k
-
1
];
myq
->
tid
[
myq
->
next
]
=
t
-
s
->
tasks
;
myq
->
count
+=
1
;
myq
->
next
+=
1
;
if
(
lock_unlock
(
&
myq
->
lock
)
!=
0
)
error
(
"Failed to unlock queue."
);
}
t
=
queue_gettask_new
(
queues
[
qid
]
,
rt
->
id
,
0
,
keep
);
if
(
t
!=
NULL
&&
keep
)
queue_insert
(
myq
,
t
);
TIMER_TOC2
(
runner_timer_steal
);
}
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment