Skip to content

Commit

Permalink
Auto PR from release/0.8 to main (#562)
Browse files Browse the repository at this point in the history
* Fix pooled stack allocator in-pool size calculation (#542)

Signed-off-by: Coldwings <coldwings@me.com>

* fix fstack-dpdk build in release/0.8 (#547)

* add fstack CI (#549)

* thread_yield() possible to return error_number obtained from thread_interrupt() (#560)

---------

Signed-off-by: Coldwings <coldwings@me.com>
Co-authored-by: Coldwings <coldwings@me.com>
Co-authored-by: Bob Chen <beef9999@qq.com>
Co-authored-by: Huiba Li <huiba.lhb@alibaba-inc.com>
  • Loading branch information
4 people committed Sep 18, 2024
1 parent 44abd5c commit 1ab47b4
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 21 deletions.
2 changes: 1 addition & 1 deletion common/lockfree_queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ struct ThreadPause : PauseBase {
};

namespace photon {
void thread_yield();
int thread_yield();
}
struct PhotonPause : PauseBase {
inline static __attribute__((always_inline)) void pause() {
Expand Down
49 changes: 31 additions & 18 deletions thread/thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1162,41 +1162,44 @@ R"(
return (states) th->state;
}

void thread_yield()
int thread_yield()
{
assert(!AtomicRunQ().single());
auto sw = AtomicRunQ().goto_next();
RunQ rq;
if_update_now();
rq.current->error_number = 0;
auto sw = AtomicRunQ(rq).goto_next();
switch_context(sw.from, sw.to);
return rq.current->error_number;
}

void thread_yield_fast() {
assert(!AtomicRunQ().single());
inline void thread_yield_fast() {
auto sw = AtomicRunQ().goto_next();
switch_context(sw.from, sw.to);
}

void thread_yield_to(thread* th) {
int thread_yield_to(thread* th) {
if (unlikely(th == nullptr)) { // yield to any thread
return thread_yield();
}
RunQ rq;
if (unlikely(th == rq.current)) { // yield to current should just update time
if_update_now();
return;
return 0;
} else if (unlikely(th->vcpu != rq.current->vcpu)) {
LOG_ERROR_RETURN(EINVAL, , "target thread ` must be run by the same vcpu as CURRENT!", th);
LOG_ERROR_RETURN(EINVAL, -1, "target thread ` must be run by the same vcpu as CURRENT!", th);
} else if (unlikely(th->state == states::STANDBY)) {
while (th->state == states::STANDBY)
resume_threads();
assert(th->state == states::READY);
} else if (unlikely(th->state != states::READY)) {
LOG_ERROR_RETURN(EINVAL, , "target thread ` must be READY!", th);
LOG_ERROR_RETURN(EINVAL, -1, "target thread ` must be READY!", th);
}

auto sw = AtomicRunQ(rq).try_goto(th);
if_update_now();
rq.current->error_number = 0;
switch_context(sw.from, sw.to);
return rq.current->error_number;
}

__attribute__((always_inline)) inline
Expand All @@ -1216,13 +1219,16 @@ R"(
sw.from->get_vcpu()->sleepq.push(sw.from);
return sw;
}

inline int yield_as_sleep() {
int ret = thread_yield();
if (unlikely(ret)) { errno = ret; return -1; }
return 0;
}
// returns 0 if slept well (at lease `useconds`), -1 otherwise
static int thread_usleep(Timeout timeout, thread_list* waitq)
{
if (unlikely(timeout.expired())) {
thread_yield();
return 0;
return yield_as_sleep();
}

auto r = prepare_usleep(timeout, waitq);
Expand Down Expand Up @@ -1292,7 +1298,7 @@ R"(
if (unlikely(!rq.current))
LOG_ERROR_RETURN(ENOSYS, -1, "Photon not initialized in this thread");
if (unlikely(timeout.expired()))
return thread_yield(), 0;
return yield_as_sleep();
if (unlikely(rq.current->is_shutting_down()))
return do_shutdown_usleep(timeout, rq);
return do_thread_usleep(timeout, rq);
Expand All @@ -1319,9 +1325,16 @@ R"(
{
if (unlikely(!th))
LOG_ERROR_RETURN(EINVAL, , "invalid parameter");
if (unlikely(th->state != states::SLEEPING)) return;
auto state = th->state;
if (unlikely(state != states::SLEEPING)) {
out: // may have thread_yield()-ed
if (state == states::READY && th->error_number == 0)
th->error_number = error_number;
return;
}
SCOPED_LOCK(th->lock);
if (unlikely(th->state != states::SLEEPING)) return;
state = th->state;
if (unlikely(state != states::SLEEPING)) goto out;

prelocked_thread_interrupt(th, error_number);
}
Expand Down Expand Up @@ -1550,9 +1563,9 @@ R"(
int mutex::lock(Timeout timeout) {
if (try_lock() == 0) return 0;
for (auto re = retries; re; --re) {
thread_yield();
if (try_lock() == 0)
return 0;
int ret = thread_yield();
if (unlikely(ret)) { errno = ret; return -1; }
if (try_lock() == 0) return 0;
}
splock.lock();
if (try_lock() == 0) {
Expand Down
6 changes: 4 additions & 2 deletions thread/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,12 @@ namespace photon
void thread_join(join_handle* jh);

// switching to other threads (without going into sleep queue)
void thread_yield();
// return error_number if interrupted during the rolling
int thread_yield();

// switching to a specific thread, which must be RUNNING
void thread_yield_to(thread* th);
// return error_number if interrupted during the rolling
int thread_yield_to(thread* th);

// suspend CURRENT thread for specified time duration, and switch
// control to other threads, resuming possible sleepers.
Expand Down

0 comments on commit 1ab47b4

Please sign in to comment.