Revision c2764719

b/cpu-defs.h
203 203
    jmp_buf jmp_env;                                                    \
204 204
    int exception_index;                                                \
205 205
                                                                        \
206
    void *next_cpu; /* next CPU sharing TB cache */                     \
206
    CPUState *next_cpu; /* next CPU sharing TB cache */                 \
207 207
    int cpu_index; /* CPU index (informative) */                        \
208 208
    int running; /* Nonzero if cpu is currently running(usermode).  */  \
209 209
    /* user data */                                                     \
b/exec.c
534 534
    CPUState **penv;
535 535
    int cpu_index;
536 536

  
537
#if defined(CONFIG_USER_ONLY)
538
    cpu_list_lock();
539
#endif
537 540
    env->next_cpu = NULL;
538 541
    penv = &first_cpu;
539 542
    cpu_index = 0;
......
545 548
    TAILQ_INIT(&env->breakpoints);
546 549
    TAILQ_INIT(&env->watchpoints);
547 550
    *penv = env;
551
#if defined(CONFIG_USER_ONLY)
552
    cpu_list_unlock();
553
#endif
548 554
#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
549 555
    register_savevm("cpu_common", cpu_index, CPU_COMMON_SAVE_VERSION,
550 556
                    cpu_common_save, cpu_common_load, env);
b/linux-user/main.c
143 143
   We don't require a full sync, only that no cpus are executing guest code.
144 144
   The alternative is to map target atomic ops onto host equivalents,
145 145
   which requires quite a lot of per host/target work.  */
146
static pthread_mutex_t cpu_list_mutex = PTHREAD_MUTEX_INITIALIZER;
146 147
static pthread_mutex_t exclusive_lock = PTHREAD_MUTEX_INITIALIZER;
147 148
static pthread_cond_t exclusive_cond = PTHREAD_COND_INITIALIZER;
148 149
static pthread_cond_t exclusive_resume = PTHREAD_COND_INITIALIZER;
......
165 166
        thread_env->next_cpu = NULL;
166 167
        pending_cpus = 0;
167 168
        pthread_mutex_init(&exclusive_lock, NULL);
169
        pthread_mutex_init(&cpu_list_mutex, NULL);
168 170
        pthread_cond_init(&exclusive_cond, NULL);
169 171
        pthread_cond_init(&exclusive_resume, NULL);
170 172
        pthread_mutex_init(&tb_lock, NULL);
......
237 239
    exclusive_idle();
238 240
    pthread_mutex_unlock(&exclusive_lock);
239 241
}
242

  
243
void cpu_list_lock(void)
244
{
245
    pthread_mutex_lock(&cpu_list_mutex);
246
}
247

  
248
void cpu_list_unlock(void)
249
{
250
    pthread_mutex_unlock(&cpu_list_mutex);
251
}
240 252
#else /* if !USE_NPTL */
241 253
/* These are no-ops because we are not threadsafe.  */
242 254
static inline void cpu_exec_start(CPUState *env)
......
265 277
        gdbserver_fork(thread_env);
266 278
    }
267 279
}
280

  
281
void cpu_list_lock(void)
282
{
283
}
284

  
285
void cpu_list_unlock(void)
286
{
287
}
268 288
#endif
269 289

  
270 290

  
b/linux-user/qemu.h
100 100
    uint32_t v86flags;
101 101
    uint32_t v86mask;
102 102
#endif
103
#ifdef USE_NPTL
104
    abi_ulong child_tidptr;
105
#endif
103 106
#ifdef TARGET_M68K
104 107
    int sim_syscalls;
105 108
#endif
......
225 228
extern unsigned long last_brk;
226 229
void mmap_lock(void);
227 230
void mmap_unlock(void);
231
void cpu_list_lock(void);
232
void cpu_list_unlock(void);
228 233
#if defined(USE_NPTL)
229 234
void mmap_fork_start(void);
230 235
void mmap_fork_end(int child);
b/linux-user/signal.c
2691 2691
    return err;
2692 2692
}
2693 2693

  
2694
static int restore_sigcontext(struct CPUState *regs,
2694
static int restore_sigcontext(CPUState *regs,
2695 2695
			      struct target_sigcontext *sc)
2696 2696
{
2697 2697
    unsigned int err = 0;
b/linux-user/syscall.c
156 156
}
157 157

  
158 158

  
159
#define __NR_sys_exit __NR_exit
160 159
#define __NR_sys_uname __NR_uname
161 160
#define __NR_sys_faccessat __NR_faccessat
162 161
#define __NR_sys_fchmodat __NR_fchmodat
......
198 197
    return -ENOSYS;
199 198
}
200 199
#endif
201
_syscall1(int,sys_exit,int,status)
202 200
_syscall1(int,sys_uname,struct new_utsname *,buf)
203 201
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
204 202
_syscall4(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode,int,flags)
......
2936 2934
        nptl_flags = flags;
2937 2935
        flags &= ~CLONE_NPTL_FLAGS2;
2938 2936

  
2939
        /* TODO: Implement CLONE_CHILD_CLEARTID.  */
2937
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
2938
            ts->child_tidptr = child_tidptr;
2939
        }
2940

  
2940 2941
        if (nptl_flags & CLONE_SETTLS)
2941 2942
            cpu_set_tls (new_env, newtls);
2942 2943

  
......
2961 2962
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
2962 2963

  
2963 2964
        ret = pthread_create(&info.thread, &attr, clone_func, &info);
2965
        /* TODO: Free new CPU state if thread creation failed.  */
2964 2966

  
2965 2967
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
2966 2968
        pthread_attr_destroy(&attr);
......
3011 3013
            ts = (TaskState *)env->opaque;
3012 3014
            if (flags & CLONE_SETTLS)
3013 3015
                cpu_set_tls (env, newtls);
3014
            /* TODO: Implement CLONE_CHILD_CLEARTID.  */
3016
            if (flags & CLONE_CHILD_CLEARTID)
3017
                ts->child_tidptr = child_tidptr;
3015 3018
#endif
3016 3019
        } else {
3017 3020
            fork_end(0);
......
3428 3431

  
3429 3432
    switch(num) {
3430 3433
    case TARGET_NR_exit:
3434
#ifdef USE_NPTL
3435
      /* In old applications this may be used to implement _exit(2).
3436
         However in threaded applictions it is used for thread termination,
3437
         and _exit_group is used for application termination.
3438
         Do thread termination if we have more then one thread.  */
3439
      /* FIXME: This probably breaks if a signal arrives.  We should probably
3440
         be disabling signals.  */
3441
      if (first_cpu->next_cpu) {
3442
          CPUState **lastp;
3443
          CPUState *p;
3444

  
3445
          cpu_list_lock();
3446
          lastp = &first_cpu;
3447
          p = first_cpu;
3448
          while (p && p != (CPUState *)cpu_env) {
3449
              lastp = &p->next_cpu;
3450
              p = p->next_cpu;
3451
          }
3452
          /* If we didn't find the CPU for this thread then something is
3453
             horribly wrong.  */
3454
          if (!p)
3455
              abort();
3456
          /* Remove the CPU from the list.  */
3457
          *lastp = p->next_cpu;
3458
          cpu_list_unlock();
3459
          TaskState *ts = ((CPUState *)cpu_env)->opaque;
3460
          if (ts->child_tidptr) {
3461
              put_user_u32(0, ts->child_tidptr);
3462
              sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
3463
                        NULL, NULL, 0);
3464
          }
3465
          /* TODO: Free CPU state.  */
3466
          pthread_exit(NULL);
3467
      }
3468
#endif
3431 3469
#ifdef HAVE_GPROF
3432 3470
        _mcleanup();
3433 3471
#endif
3434 3472
        gdb_exit(cpu_env, arg1);
3435
        /* XXX: should free thread stack and CPU env */
3436
        sys_exit(arg1);
3473
        _exit(arg1);
3437 3474
        ret = 0; /* avoid warning */
3438 3475
        break;
3439 3476
    case TARGET_NR_read:
b/target-alpha/cpu.h
25 25

  
26 26
#define TARGET_LONG_BITS 64
27 27

  
28
#define CPUState struct CPUAlphaState
29

  
28 30
#include "cpu-defs.h"
29 31

  
30 32
#include <setjmp.h>
......
291 293
    pal_handler_t *pal_handler;
292 294
};
293 295

  
294
#define CPUState CPUAlphaState
295 296
#define cpu_init cpu_alpha_init
296 297
#define cpu_exec cpu_alpha_exec
297 298
#define cpu_gen_code cpu_alpha_gen_code
b/target-arm/cpu.h
24 24

  
25 25
#define ELF_MACHINE	EM_ARM
26 26

  
27
#define CPUState struct CPUARMState
28

  
27 29
#include "cpu-defs.h"
28 30

  
29 31
#include "softfloat.h"
......
398 400
#define TARGET_PAGE_BITS 10
399 401
#endif
400 402

  
401
#define CPUState CPUARMState
402 403
#define cpu_init cpu_arm_init
403 404
#define cpu_exec cpu_arm_exec
404 405
#define cpu_gen_code cpu_arm_gen_code
b/target-cris/cpu.h
23 23

  
24 24
#define TARGET_LONG_BITS 32
25 25

  
26
#define CPUState struct CPUCRISState
27

  
26 28
#include "cpu-defs.h"
27 29

  
28 30
#define TARGET_HAS_ICE 1
......
199 201
#define TARGET_PAGE_BITS 13
200 202
#define MMAP_SHIFT TARGET_PAGE_BITS
201 203

  
202
#define CPUState CPUCRISState
203 204
#define cpu_init cpu_cris_init
204 205
#define cpu_exec cpu_cris_exec
205 206
#define cpu_gen_code cpu_cris_gen_code
b/target-i386/cpu.h
42 42
#define ELF_MACHINE	EM_386
43 43
#endif
44 44

  
45
#define CPUState struct CPUX86State
46

  
45 47
#include "cpu-defs.h"
46 48

  
47 49
#include "softfloat.h"
......
828 830

  
829 831
#define TARGET_PAGE_BITS 12
830 832

  
831
#define CPUState CPUX86State
832 833
#define cpu_init cpu_x86_init
833 834
#define cpu_exec cpu_x86_exec
834 835
#define cpu_gen_code cpu_x86_gen_code
b/target-m68k/cpu.h
23 23

  
24 24
#define TARGET_LONG_BITS 32
25 25

  
26
#define CPUState struct CPUM68KState
27

  
26 28
#include "cpu-defs.h"
27 29

  
28 30
#include "softfloat.h"
......
207 209
#define TARGET_PAGE_BITS 10
208 210
#endif
209 211

  
210
#define CPUState CPUM68KState
211 212
#define cpu_init cpu_m68k_init
212 213
#define cpu_exec cpu_m68k_exec
213 214
#define cpu_gen_code cpu_m68k_gen_code
b/target-mips/cpu.h
5 5

  
6 6
#define ELF_MACHINE	EM_MIPS
7 7

  
8
#define CPUState struct CPUMIPSState
9

  
8 10
#include "config.h"
9 11
#include "mips-defs.h"
10 12
#include "cpu-defs.h"
......
473 475
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
474 476
                          int unused, int size);
475 477

  
476
#define CPUState CPUMIPSState
477 478
#define cpu_init cpu_mips_init
478 479
#define cpu_exec cpu_mips_exec
479 480
#define cpu_gen_code cpu_mips_gen_code
b/target-ppc/cpu.h
54 54

  
55 55
#endif /* defined (TARGET_PPC64) */
56 56

  
57
#define CPUState struct CPUPPCState
58

  
57 59
#include "cpu-defs.h"
58 60

  
59 61
#define REGX "%016" PRIx64
......
786 788
int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, target_ulong *valp);
787 789
int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val);
788 790

  
789
#define CPUState CPUPPCState
790 791
#define cpu_init cpu_ppc_init
791 792
#define cpu_exec cpu_ppc_exec
792 793
#define cpu_gen_code cpu_ppc_gen_code
b/target-sh4/cpu.h
37 37
#define SH_CPU_SH7750_ALL (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7750R)
38 38
#define SH_CPU_SH7751_ALL (SH_CPU_SH7751 | SH_CPU_SH7751R)
39 39

  
40
#define CPUState struct CPUSH4State
41

  
40 42
#include "cpu-defs.h"
41 43

  
42 44
#include "softfloat.h"
......
169 171

  
170 172
#include "softfloat.h"
171 173

  
172
#define CPUState CPUSH4State
173 174
#define cpu_init cpu_sh4_init
174 175
#define cpu_exec cpu_sh4_exec
175 176
#define cpu_gen_code cpu_sh4_gen_code
b/target-sparc/cpu.h
15 15

  
16 16
#define TARGET_PHYS_ADDR_BITS 64
17 17

  
18
#define CPUState struct CPUSPARCState
19

  
18 20
#include "cpu-defs.h"
19 21

  
20 22
#include "softfloat.h"
......
436 438
                          int is_asi, int size);
437 439
int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
438 440

  
439
#define CPUState CPUSPARCState
440 441
#define cpu_init cpu_sparc_init
441 442
#define cpu_exec cpu_sparc_exec
442 443
#define cpu_gen_code cpu_sparc_gen_code

Also available in: Unified diff