Changeset 80649a91 in mainline for libc/generic/psthread.c
- Timestamp:
- 2006-05-21T19:28:37Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a410beb
- Parents:
- 1ee11f4
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libc/generic/psthread.c
r1ee11f4 r80649a91 34 34 #include <stdio.h> 35 35 #include <kernel/arch/faddr.h> 36 36 #include <futex.h> 37 #include <assert.h> 37 38 38 39 #ifndef PSTHREAD_INITIAL_STACK_PAGES_NO … … 41 42 42 43 static LIST_INITIALIZE(ready_list); 44 static LIST_INITIALIZE(manager_list); 43 45 44 46 static void psthread_exit(void) __attribute__ ((noinline)); 45 47 static void psthread_main(void); 46 48 49 static atomic_t psthread_futex = FUTEX_INITIALIZER; 50 47 51 /** Setup PSthread information into TCB structure */ 48 psthread_data_t * psthread_setup(tcb_t *tcb) 49 { 50 psthread_data_t *pt; 52 psthread_data_t * psthread_setup() 53 { 54 psthread_data_t *pt; 55 tcb_t *tcb; 56 57 tcb = __make_tls(); 58 if (!tcb) 59 return NULL; 51 60 52 61 pt = malloc(sizeof(*pt)); 53 62 if (!pt) { 63 __free_tls(tcb); 54 64 return NULL; 55 65 } … … 63 73 void psthread_teardown(psthread_data_t *pt) 64 74 { 75 __free_tls(pt->tcb); 65 76 free(pt); 66 77 } … … 73 84 psthread_data_t *pt; 74 85 75 if (list_empty(&ready_list)) { 76 /* Wait on IPC queue etc... */ 77 printf("Cannot exit!!!\n"); 86 futex_down(&psthread_futex); 87 88 if (!list_empty(&ready_list)) 89 pt = list_get_instance(ready_list.next, psthread_data_t, link); 90 else if (!list_empty(&manager_list)) 91 pt = list_get_instance(manager_list.next, psthread_data_t, link); 92 else { 93 printf("Cannot find suitable psthread to run.\n"); 78 94 _exit(0); 79 95 } 80 pt = list_get_instance(ready_list.next, psthread_data_t, link);81 96 list_remove(&pt->link); 97 futex_up(&psthread_futex); 98 82 99 context_restore(&pt->ctx); 100 /* Never reached */ 83 101 } 84 102 … … 99 117 /** Schedule next userspace pseudo thread. 100 118 * 119 * @param tomanager If true, we are switching to next ready manager thread 120 * (if none is found, thread is exited) 121 * @param frommanager If true, we are switching from manager thread 101 122 * @return 0 if there is no ready pseudo thread, 1 otherwise. 102 123 */ 103 int psthread_schedule_next(void) 104 { 105 psthread_data_t *pt; 106 107 if (list_empty(&ready_list)) 108 return 0; 124 int psthread_schedule_next_adv(pschange_type ctype) 125 { 126 psthread_data_t *pt; 127 int retval = 0; 128 129 futex_down(&psthread_futex); 130 131 if (ctype == PS_PREEMPT && list_empty(&ready_list)) 132 goto ret_0; 133 134 if (ctype == PS_FROM_MANAGER && list_empty(&ready_list)) { 135 goto ret_0; 136 } 137 assert(!(ctype == PS_TO_MANAGER && list_empty(&manager_list))); 109 138 110 139 pt = __tcb_get()->pst_data; 111 if (!context_save(&pt->ctx)) 112 return 1; 140 if (!context_save(&pt->ctx)) 141 return 1; // futex_up already done here 142 143 if (ctype == PS_PREEMPT) 144 list_append(&pt->link, &ready_list); 145 else if (ctype == PS_FROM_MANAGER) 146 list_append(&pt->link, &manager_list); 113 147 114 list_append(&pt->link, &ready_list); 115 pt = list_get_instance(ready_list.next, psthread_data_t, link); 148 if (ctype == PS_TO_MANAGER) 149 pt = list_get_instance(manager_list.next,psthread_data_t, link); 150 else 151 pt = list_get_instance(ready_list.next, psthread_data_t, link); 116 152 list_remove(&pt->link); 117 153 154 futex_up(&psthread_futex); 118 155 context_restore(&pt->ctx); 156 157 ret_0: 158 futex_up(&psthread_futex); 159 return retval; 119 160 } 120 161 … … 143 184 144 185 free(pt->stack); 145 __free_tls(pt->tcb);146 186 psthread_teardown((void *)pt); 147 187 … … 150 190 151 191 /** 152 * Create a userspace thread and append it to ready list.192 * Create a userspace thread 153 193 * 154 194 * @param func Pseudo thread function. … … 160 200 { 161 201 psthread_data_t *pt; 162 tcb_t *tcb; 163 164 tcb = __make_tls(); 165 if (!tcb) 202 203 pt = psthread_setup(); 204 if (!pt) 166 205 return 0; 167 168 pt = psthread_setup(tcb);169 if (!pt) {170 __free_tls(tcb);171 return 0;172 }173 206 pt->stack = (char *) malloc(PSTHREAD_INITIAL_STACK_PAGES_NO*getpagesize()); 174 207 175 208 if (!pt->stack) { 176 __free_tls(tcb);177 209 psthread_teardown(pt); 178 210 return 0; … … 186 218 context_save(&pt->ctx); 187 219 context_set(&pt->ctx, FADDR(psthread_main), pt->stack, PSTHREAD_INITIAL_STACK_PAGES_NO*getpagesize(), 188 tcb); 189 220 pt->tcb); 221 222 return (pstid_t )pt; 223 } 224 225 /** Add a thread to ready list */ 226 void psthread_add_ready(pstid_t psthrid) 227 { 228 psthread_data_t *pt; 229 230 pt = (psthread_data_t *) psthrid; 231 futex_down(&psthread_futex); 190 232 list_append(&pt->link, &ready_list); 191 192 return (pstid_t )pt; 193 } 233 futex_up(&psthread_futex); 234 } 235 236 /** Add a thread to manager list */ 237 void psthread_add_manager(pstid_t psthrid) 238 { 239 psthread_data_t *pt; 240 241 pt = (psthread_data_t *) psthrid; 242 243 futex_down(&psthread_futex); 244 list_append(&pt->link, &manager_list); 245 futex_up(&psthread_futex); 246 } 247 248 /** Remove one manager from manager list */ 249 void psthread_remove_manager() 250 { 251 futex_down(&psthread_futex); 252 if (list_empty(&manager_list)) { 253 printf("No manager found!.\n"); 254 futex_up(&psthread_futex); 255 return; 256 } 257 list_remove(manager_list.next); 258 futex_up(&psthread_futex); 259 }
Note:
See TracChangeset
for help on using the changeset viewer.