Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
LARN
PRRT
Commits
def4cf26
Commit
def4cf26
authored
Jul 01, 2019
by
Stefan Reif
Browse files
timer
parent
7fa6a50b
Pipeline
#3781
failed with stages
in 12363 minutes and 4 seconds
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
prrt/proto/timer.c
View file @
def4cf26
...
...
@@ -133,7 +133,7 @@ struct prrtTimer {
atomic_int
wait
;
_Atomic
(
TimerNode
*
)
new
;
_Atomic
(
TimerNode
*
)
old
;
_Atomic
(
TimerNode
*
)
del
;
_Atomic
(
TimerNode
*
)
cur
;
TimerDateUDiff_t
precision
;
TimerDateUDiff_t
lcp
;
TimerDateUDiff_t
osp
;
...
...
@@ -143,7 +143,7 @@ struct prrtTimer {
typedef
struct
prrtTimer
Timer
;
static
bool
timer_date_is_due
(
Timer
*
self
,
TimerDate
*
when
,
const
TimerDate
*
now
)
static
bool
timer_date_is_due
(
Timer
*
self
,
const
TimerDate
*
when
,
const
TimerDate
*
now
)
{
// TODO: use self->precision to check whether now and *when are similar enough
(
void
)
self
;
...
...
@@ -208,6 +208,8 @@ static void *timer_worker_loop(void *arg)
TimerNode
*
task
=
atomic_load
(
&
self
->
new
);
assert
(
task
!=
NULL
&&
"task list contains NULL node"
);
atomic_store
(
&
self
->
cur
,
task
);
if
(
timer_date_is_inf
(
&
task
->
date
))
{
if
(
!
atomic_load_explicit
(
&
self
->
alive
,
memory_order_acquire
))
{
if
(
task
==
atomic_load
(
&
self
->
new
))
...
...
@@ -260,11 +262,9 @@ static void *timer_worker_loop(void *arg)
task
->
done
=
true
;
}
atomic_store
(
&
self
->
del
,
task
);
TimerNode
*
next
=
atomic_load
(
&
task
->
next
);
TimerNode
*
temp
=
task
;
atomic_compare_exchange_strong
(
&
self
->
new
,
&
temp
,
next
);
atomic_store
(
&
self
->
del
,
NULL
);
if
(
slept
&&
!
learned
)
{
clock_gettime
(
CLOCK_REALTIME
,
&
td1
);
...
...
@@ -306,7 +306,7 @@ PrrtTimer *PrrtTimer_create(unsigned int core)
atomic_store_explicit
(
&
self
->
wait
,
0
,
memory_order_relaxed
);
atomic_store_explicit
(
&
self
->
new
,
node
,
memory_order_relaxed
);
atomic_store_explicit
(
&
self
->
old
,
node
,
memory_order_relaxed
);
atomic_store_explicit
(
&
self
->
del
,
NULL
,
memory_order_relaxed
);
atomic_store_explicit
(
&
self
->
cur
,
node
,
memory_order_relaxed
);
self
->
precision
=
timer_measure_clock_precision
();
for
(
int
i
=
0
;
i
<
OSP_WINDOW_SIZE
;
i
++
)
...
...
@@ -364,7 +364,7 @@ PrrtTimer *PrrtTimer_create(unsigned int core)
int
PrrtTimer_submit
(
PrrtTimer
*
self
,
const
TimerDate
*
when
,
const
PrrtTimerTask
*
what
)
{
TimerNode
*
iter
,
*
stop
,
*
next
;
TimerNode
*
iter
,
*
stop
,
*
next
,
*
hold
;
TimerNode
*
node
=
malloc
(
sizeof
(
TimerNode
));
if
(
!
node
)
return
-
1
;
...
...
@@ -380,13 +380,14 @@ int PrrtTimer_submit(PrrtTimer *self, const TimerDate *when, const PrrtTimerTask
iter
=
atomic_load
(
&
self
->
old
);
stop
=
atomic_load
(
&
self
->
new
);
while
(
iter
!=
stop
)
{
hold
=
atomic_load
(
&
self
->
cur
);
while
(
iter
!=
stop
&&
iter
!=
hold
)
{
next
=
iter
->
next
;
assert
(
iter
->
done
&&
"cleanup task that is not marked as done"
);
free
(
iter
);
iter
=
next
;
}
atomic_store
(
&
self
->
old
,
stop
);
atomic_store
(
&
self
->
old
,
iter
);
_Atomic
(
TimerNode
*
)
*
addr
=
&
self
->
old
;
while
(
1
)
{
...
...
@@ -407,9 +408,8 @@ int PrrtTimer_submit(PrrtTimer *self, const TimerDate *when, const PrrtTimerTask
atomic_store
(
&
node
->
next
,
iter
);
atomic_store
(
addr
,
node
);
TimerNode
*
del
=
atomic_load
(
&
self
->
del
);
TimerNode
*
tail
=
atomic_load
(
&
self
->
new
);
if
(
del
==
tail
||
timer_date_is_lt
(
&
node
->
date
,
&
tail
->
date
))
{
if
(
timer_date_is_lt
(
&
node
->
date
,
&
tail
->
date
)
||
(
addr
==
&
tail
->
next
&&
atomic_load
(
&
tail
->
done
))
)
{
atomic_store
(
&
self
->
new
,
node
);
timer_wake_worker
(
self
,
false
);
}
...
...
@@ -417,6 +417,50 @@ int PrrtTimer_submit(PrrtTimer *self, const TimerDate *when, const PrrtTimerTask
return
-
1
;
}
static
void
wake_sleeping_thread
(
void
*
arg
)
{
atomic_int
*
ip
=
(
atomic_int
*
)
arg
;
atomic_store_explicit
(
ip
,
1
,
memory_order_release
);
futex
((
int
*
)
ip
,
FUTEX_WAKE
|
FUTEX_PRIVATE_FLAG
,
1
,
NULL
,
NULL
,
0
);
}
void
PrrtTimer_sleep_until
(
PrrtTimer
*
self
,
const
TimerDate
*
end
)
{
atomic_int
cond
;
atomic_store_explicit
(
&
cond
,
0
,
memory_order_release
);
TimerDate
now
;
TimerDate
care
=
*
end
;
PrrtTimerTask
what
;
what
.
fun
=
wake_sleeping_thread
;
what
.
arg
=
&
cond
;
timer_date_sub
(
&
care
,
2
*
self
->
osp
);
clock_gettime
(
CLOCK_REALTIME
,
&
now
);
if
(
!
timer_date_is_due
(
self
,
&
care
,
&
now
))
{
PrrtTimer_submit
(
self
,
&
care
,
&
what
);
while
(
!
atomic_load
(
&
cond
))
{
clock_gettime
(
CLOCK_REALTIME
,
&
now
);
if
(
!
timer_date_is_due
(
self
,
&
care
,
&
now
))
//futex(&cond, FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME, 1, care, NULL, FUTEX_BITSET_MATCH_ANY);
futex
(
&
cond
,
FUTEX_WAIT
|
FUTEX_PRIVATE_FLAG
,
0
,
NULL
,
NULL
,
0
);
}
}
while
(
1
)
{
clock_gettime
(
CLOCK_REALTIME
,
&
now
);
if
(
timer_date_is_due
(
self
,
end
,
&
now
))
break
;
}
}
void
PrrtTimer_sleep_nanos
(
PrrtTimer
*
self
,
TimerDateUDiff_t
nanos
)
{
TimerDate
when
;
clock_gettime
(
CLOCK_REALTIME
,
&
when
);
timer_date_add
(
&
when
,
nanos
);
PrrtTimer_sleep_until
(
self
,
&
when
);
}
void
PrrtTimer_end
(
PrrtTimer
*
self
)
{
atomic_store_explicit
(
&
self
->
alive
,
false
,
memory_order_release
);
...
...
prrt/proto/timer.h
View file @
def4cf26
...
...
@@ -10,6 +10,7 @@ typedef void *prrtTimerTaskArg;
typedef
void
(
*
prrtTimerTaskFun
)(
prrtTimerTaskArg
);
typedef
struct
timespec
prrtTimerDate
;
typedef
unsigned
long
long
TimerDateUDiff_t
;
typedef
struct
prrtTimerTask
{
prrtTimerTaskFun
fun
;
...
...
@@ -24,4 +25,7 @@ int PrrtTimer_submit(PrrtTimer *timer, const prrtTimerDate *when, const PrrtTime
void
PrrtTimer_end
(
PrrtTimer
*
timer
);
void
PrrtTimer_sleep_until
(
PrrtTimer
*
self
,
const
prrtTimerDate
*
end
);
void
PrrtTimer_sleep_nanos
(
PrrtTimer
*
self
,
TimerDateUDiff_t
nanos
);
#endif // PRRT_TIMER_H
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a 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