root / coroutine-gthread.c @ 9f4facbc
History | View | Annotate | Download (3.6 kB)
1 | d0e2fce5 | Aneesh Kumar K.V | /*
|
---|---|---|---|
2 | d0e2fce5 | Aneesh Kumar K.V | * GThread coroutine initialization code
|
3 | d0e2fce5 | Aneesh Kumar K.V | *
|
4 | d0e2fce5 | Aneesh Kumar K.V | * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
|
5 | d0e2fce5 | Aneesh Kumar K.V | * Copyright (C) 2011 Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
|
6 | d0e2fce5 | Aneesh Kumar K.V | *
|
7 | d0e2fce5 | Aneesh Kumar K.V | * This library is free software; you can redistribute it and/or
|
8 | d0e2fce5 | Aneesh Kumar K.V | * modify it under the terms of the GNU Lesser General Public
|
9 | d0e2fce5 | Aneesh Kumar K.V | * License as published by the Free Software Foundation; either
|
10 | d0e2fce5 | Aneesh Kumar K.V | * version 2.0 of the License, or (at your option) any later version.
|
11 | d0e2fce5 | Aneesh Kumar K.V | *
|
12 | d0e2fce5 | Aneesh Kumar K.V | * This library is distributed in the hope that it will be useful,
|
13 | d0e2fce5 | Aneesh Kumar K.V | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 | d0e2fce5 | Aneesh Kumar K.V | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15 | d0e2fce5 | Aneesh Kumar K.V | * Lesser General Public License for more details.
|
16 | d0e2fce5 | Aneesh Kumar K.V | *
|
17 | d0e2fce5 | Aneesh Kumar K.V | * You should have received a copy of the GNU Lesser General Public
|
18 | d0e2fce5 | Aneesh Kumar K.V | * License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
19 | d0e2fce5 | Aneesh Kumar K.V | */
|
20 | d0e2fce5 | Aneesh Kumar K.V | |
21 | d0e2fce5 | Aneesh Kumar K.V | #include <glib.h> |
22 | d0e2fce5 | Aneesh Kumar K.V | #include "qemu-common.h" |
23 | d0e2fce5 | Aneesh Kumar K.V | #include "qemu-coroutine-int.h" |
24 | d0e2fce5 | Aneesh Kumar K.V | |
25 | d0e2fce5 | Aneesh Kumar K.V | typedef struct { |
26 | d0e2fce5 | Aneesh Kumar K.V | Coroutine base; |
27 | d0e2fce5 | Aneesh Kumar K.V | GThread *thread; |
28 | d0e2fce5 | Aneesh Kumar K.V | bool runnable;
|
29 | d0e2fce5 | Aneesh Kumar K.V | CoroutineAction action; |
30 | d0e2fce5 | Aneesh Kumar K.V | } CoroutineGThread; |
31 | d0e2fce5 | Aneesh Kumar K.V | |
32 | d0e2fce5 | Aneesh Kumar K.V | static GCond *coroutine_cond;
|
33 | d0e2fce5 | Aneesh Kumar K.V | static GStaticMutex coroutine_lock = G_STATIC_MUTEX_INIT;
|
34 | d0e2fce5 | Aneesh Kumar K.V | static GStaticPrivate coroutine_key = G_STATIC_PRIVATE_INIT;
|
35 | d0e2fce5 | Aneesh Kumar K.V | |
36 | d0e2fce5 | Aneesh Kumar K.V | static void __attribute__((constructor)) coroutine_init(void) |
37 | d0e2fce5 | Aneesh Kumar K.V | { |
38 | d0e2fce5 | Aneesh Kumar K.V | if (!g_thread_supported()) {
|
39 | d0e2fce5 | Aneesh Kumar K.V | g_thread_init(NULL);
|
40 | d0e2fce5 | Aneesh Kumar K.V | } |
41 | d0e2fce5 | Aneesh Kumar K.V | |
42 | d0e2fce5 | Aneesh Kumar K.V | coroutine_cond = g_cond_new(); |
43 | d0e2fce5 | Aneesh Kumar K.V | } |
44 | d0e2fce5 | Aneesh Kumar K.V | |
45 | d0e2fce5 | Aneesh Kumar K.V | static void coroutine_wait_runnable_locked(CoroutineGThread *co) |
46 | d0e2fce5 | Aneesh Kumar K.V | { |
47 | d0e2fce5 | Aneesh Kumar K.V | while (!co->runnable) {
|
48 | d0e2fce5 | Aneesh Kumar K.V | g_cond_wait(coroutine_cond, g_static_mutex_get_mutex(&coroutine_lock)); |
49 | d0e2fce5 | Aneesh Kumar K.V | } |
50 | d0e2fce5 | Aneesh Kumar K.V | } |
51 | d0e2fce5 | Aneesh Kumar K.V | |
52 | d0e2fce5 | Aneesh Kumar K.V | static void coroutine_wait_runnable(CoroutineGThread *co) |
53 | d0e2fce5 | Aneesh Kumar K.V | { |
54 | d0e2fce5 | Aneesh Kumar K.V | g_static_mutex_lock(&coroutine_lock); |
55 | d0e2fce5 | Aneesh Kumar K.V | coroutine_wait_runnable_locked(co); |
56 | d0e2fce5 | Aneesh Kumar K.V | g_static_mutex_unlock(&coroutine_lock); |
57 | d0e2fce5 | Aneesh Kumar K.V | } |
58 | d0e2fce5 | Aneesh Kumar K.V | |
59 | d0e2fce5 | Aneesh Kumar K.V | static gpointer coroutine_thread(gpointer opaque)
|
60 | d0e2fce5 | Aneesh Kumar K.V | { |
61 | d0e2fce5 | Aneesh Kumar K.V | CoroutineGThread *co = opaque; |
62 | d0e2fce5 | Aneesh Kumar K.V | |
63 | d0e2fce5 | Aneesh Kumar K.V | g_static_private_set(&coroutine_key, co, NULL);
|
64 | d0e2fce5 | Aneesh Kumar K.V | coroutine_wait_runnable(co); |
65 | d0e2fce5 | Aneesh Kumar K.V | co->base.entry(co->base.entry_arg); |
66 | d0e2fce5 | Aneesh Kumar K.V | qemu_coroutine_switch(&co->base, co->base.caller, COROUTINE_TERMINATE); |
67 | d0e2fce5 | Aneesh Kumar K.V | return NULL; |
68 | d0e2fce5 | Aneesh Kumar K.V | } |
69 | d0e2fce5 | Aneesh Kumar K.V | |
70 | d0e2fce5 | Aneesh Kumar K.V | Coroutine *qemu_coroutine_new(void)
|
71 | d0e2fce5 | Aneesh Kumar K.V | { |
72 | d0e2fce5 | Aneesh Kumar K.V | CoroutineGThread *co; |
73 | d0e2fce5 | Aneesh Kumar K.V | |
74 | 7267c094 | Anthony Liguori | co = g_malloc0(sizeof(*co));
|
75 | d0e2fce5 | Aneesh Kumar K.V | co->thread = g_thread_create_full(coroutine_thread, co, 0, TRUE, TRUE,
|
76 | d0e2fce5 | Aneesh Kumar K.V | G_THREAD_PRIORITY_NORMAL, NULL);
|
77 | d0e2fce5 | Aneesh Kumar K.V | if (!co->thread) {
|
78 | 7267c094 | Anthony Liguori | g_free(co); |
79 | d0e2fce5 | Aneesh Kumar K.V | return NULL; |
80 | d0e2fce5 | Aneesh Kumar K.V | } |
81 | d0e2fce5 | Aneesh Kumar K.V | return &co->base;
|
82 | d0e2fce5 | Aneesh Kumar K.V | } |
83 | d0e2fce5 | Aneesh Kumar K.V | |
84 | d0e2fce5 | Aneesh Kumar K.V | void qemu_coroutine_delete(Coroutine *co_)
|
85 | d0e2fce5 | Aneesh Kumar K.V | { |
86 | d0e2fce5 | Aneesh Kumar K.V | CoroutineGThread *co = DO_UPCAST(CoroutineGThread, base, co_); |
87 | d0e2fce5 | Aneesh Kumar K.V | |
88 | d0e2fce5 | Aneesh Kumar K.V | g_thread_join(co->thread); |
89 | 7267c094 | Anthony Liguori | g_free(co); |
90 | d0e2fce5 | Aneesh Kumar K.V | } |
91 | d0e2fce5 | Aneesh Kumar K.V | |
92 | d0e2fce5 | Aneesh Kumar K.V | CoroutineAction qemu_coroutine_switch(Coroutine *from_, |
93 | d0e2fce5 | Aneesh Kumar K.V | Coroutine *to_, |
94 | d0e2fce5 | Aneesh Kumar K.V | CoroutineAction action) |
95 | d0e2fce5 | Aneesh Kumar K.V | { |
96 | d0e2fce5 | Aneesh Kumar K.V | CoroutineGThread *from = DO_UPCAST(CoroutineGThread, base, from_); |
97 | d0e2fce5 | Aneesh Kumar K.V | CoroutineGThread *to = DO_UPCAST(CoroutineGThread, base, to_); |
98 | d0e2fce5 | Aneesh Kumar K.V | |
99 | d0e2fce5 | Aneesh Kumar K.V | g_static_mutex_lock(&coroutine_lock); |
100 | d0e2fce5 | Aneesh Kumar K.V | from->runnable = false;
|
101 | d0e2fce5 | Aneesh Kumar K.V | from->action = action; |
102 | d0e2fce5 | Aneesh Kumar K.V | to->runnable = true;
|
103 | d0e2fce5 | Aneesh Kumar K.V | to->action = action; |
104 | d0e2fce5 | Aneesh Kumar K.V | g_cond_broadcast(coroutine_cond); |
105 | d0e2fce5 | Aneesh Kumar K.V | |
106 | d0e2fce5 | Aneesh Kumar K.V | if (action != COROUTINE_TERMINATE) {
|
107 | d0e2fce5 | Aneesh Kumar K.V | coroutine_wait_runnable_locked(from); |
108 | d0e2fce5 | Aneesh Kumar K.V | } |
109 | d0e2fce5 | Aneesh Kumar K.V | g_static_mutex_unlock(&coroutine_lock); |
110 | d0e2fce5 | Aneesh Kumar K.V | return from->action;
|
111 | d0e2fce5 | Aneesh Kumar K.V | } |
112 | d0e2fce5 | Aneesh Kumar K.V | |
113 | d0e2fce5 | Aneesh Kumar K.V | Coroutine *qemu_coroutine_self(void)
|
114 | d0e2fce5 | Aneesh Kumar K.V | { |
115 | d0e2fce5 | Aneesh Kumar K.V | CoroutineGThread *co = g_static_private_get(&coroutine_key); |
116 | d0e2fce5 | Aneesh Kumar K.V | |
117 | d0e2fce5 | Aneesh Kumar K.V | if (!co) {
|
118 | 7267c094 | Anthony Liguori | co = g_malloc0(sizeof(*co));
|
119 | d0e2fce5 | Aneesh Kumar K.V | co->runnable = true;
|
120 | 58a06675 | Blue Swirl | g_static_private_set(&coroutine_key, co, (GDestroyNotify)g_free); |
121 | d0e2fce5 | Aneesh Kumar K.V | } |
122 | d0e2fce5 | Aneesh Kumar K.V | |
123 | d0e2fce5 | Aneesh Kumar K.V | return &co->base;
|
124 | d0e2fce5 | Aneesh Kumar K.V | } |
125 | d0e2fce5 | Aneesh Kumar K.V | |
126 | d0e2fce5 | Aneesh Kumar K.V | bool qemu_in_coroutine(void) |
127 | d0e2fce5 | Aneesh Kumar K.V | { |
128 | d0e2fce5 | Aneesh Kumar K.V | CoroutineGThread *co = g_static_private_get(&coroutine_key); |
129 | d0e2fce5 | Aneesh Kumar K.V | |
130 | d0e2fce5 | Aneesh Kumar K.V | return co && co->base.caller;
|
131 | d0e2fce5 | Aneesh Kumar K.V | } |