| 2069 | return 0; |
| 2070 | } |
| 2071 | int thread_migrate(thread* th, vcpu_base* v) { |
| 2072 | if (!th || !v) { |
| 2073 | LOG_ERROR_RETURN(EINVAL, -1, "target thread / vcpu must be specified") |
| 2074 | } |
| 2075 | if (v == CURRENT->vcpu) { |
| 2076 | return 0; |
| 2077 | } |
| 2078 | if (th == CURRENT) { |
| 2079 | return defer_migrate_current(v); |
| 2080 | } |
| 2081 | if (th->vcpu != CURRENT->vcpu) { |
| 2082 | LOG_ERROR_RETURN(EINVAL, -1, |
| 2083 | "Try to migrate thread `, which is not on current vcpu.", th) |
| 2084 | } |
| 2085 | if (th->state != READY) { |
| 2086 | LOG_ERROR_RETURN(EINVAL, -1, |
| 2087 | "Try to migrate thread `, which is not ready.", th) |
| 2088 | } |
| 2089 | return do_thread_migrate(th, v); |
| 2090 | } |
| 2091 | static int do_thread_migrate(thread* th, vcpu_base* vb) { |
| 2092 | assert(vb != th->vcpu); |
| 2093 | AtomicRunQ().remove_from_list(th); |