Revision c2764719 linux-user/syscall.c

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:

Also available in: Unified diff