Exemplo n.º 1
0
int
ruby_vm_destruct(void *ptr)
{
    RUBY_FREE_ENTER("vm");
    if (ptr) {
	rb_vm_t *vm = ptr;
	rb_thread_t *th = vm->main_thread;
#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
	struct rb_objspace *objspace = vm->objspace;
#endif
	rb_gc_force_recycle(vm->self);
	vm->main_thread = 0;
	if (th) {
	    thread_free(th);
	}
	if (vm->living_threads) {
	    st_free_table(vm->living_threads);
	    vm->living_threads = 0;
	}
	rb_thread_lock_unlock(&vm->global_vm_lock);
	rb_thread_lock_destroy(&vm->global_vm_lock);
	ruby_xfree(vm);
	ruby_current_vm = 0;
#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
	if (objspace) {
	    rb_objspace_free(objspace);
	}
#endif
    }
    RUBY_FREE_LEAVE("vm");
    return 0;
}
Exemplo n.º 2
0
void ff_thread_free(AVCodecContext *avctx)
{
    if (avctx->active_thread_type&FF_THREAD_FRAME)
        frame_thread_free(avctx, avctx->thread_count);
    else
        thread_free(avctx);
}
Exemplo n.º 3
0
int
ruby_vm_destruct(rb_vm_t *vm)
{
    RUBY_FREE_ENTER("vm");
    if (vm) {
	rb_thread_t *th = vm->main_thread;
#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
	struct rb_objspace *objspace = vm->objspace;
#endif
	rb_gc_force_recycle(vm->self);
	vm->main_thread = 0;
	if (th) {
	    thread_free(th);
	}
	if (vm->living_threads) {
	    st_free_table(vm->living_threads);
	    vm->living_threads = 0;
	}
#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
	if (objspace) {
	    rb_objspace_free(objspace);
	}
#endif
	ruby_vm_run_at_exit_hooks(vm);
	rb_vm_gvl_destroy(vm);
	ruby_xfree(vm);
	ruby_current_vm = 0;
    }
    RUBY_FREE_LEAVE("vm");
    return 0;
}
Exemplo n.º 4
0
/**
 * Internally used "receive status" thread function that will call the specified
 * callback function when status update messages (or error messages) are
 * received.
 *
 * @param arg Pointer to an allocated struct instproxy_status_data that holds
 *     the required data about the connected client and the callback function.
 *
 * @return Always NULL.
 */
static void* instproxy_receive_status_loop_thread(void* arg)
{
	struct instproxy_status_data *data = (struct instproxy_status_data*)arg;

	/* run until the command is complete or an error occurs */
	(void)instproxy_receive_status_loop(data->client, data->command, data->cbfunc, data->user_data);

	/* cleanup */
	instproxy_lock(data->client);

	debug_info("done, cleaning up.");

	if (data->command) {
		plist_free(data->command);
	}

	if (data->client->receive_status_thread) {
		thread_free(data->client->receive_status_thread);
		data->client->receive_status_thread = (thread_t)NULL;
	}

	instproxy_unlock(data->client);
	free(data);

	return NULL;
}
void thread_list_free(struct thread_list* self) {
    int t;
    for (t = 0; t < self->count; t++) {
        thread_free(&(self->threads[t]));
    }
    free(self);
}
Exemplo n.º 6
0
void hci_inject_close(void) {
  socket_free(listen_socket);
  list_free(clients);
  thread_free(thread);

  listen_socket = NULL;
  thread = NULL;
  clients = NULL;
}
Exemplo n.º 7
0
static void fiber_schedule_main_free(void)
{
	if (__main_fiber) {
		thread_free(__main_fiber);
		if (__thread_fiber == __main_fiber)
			__thread_fiber = NULL;
		__main_fiber = NULL;
	}
}
Exemplo n.º 8
0
void printer_free(NumPrinter* p){
      mutex_lock(printer_num);
      if(p->thread != NULL){
        thread_terminate(p->thread);
        thread_free(p->thread);
      }
      mutex_unlock(printer_num);

      free(p);
}
Exemplo n.º 9
0
static void fiber_io_main_free(void)
{
	if (__main_fiber) {
		thread_free(__main_fiber);
		if (__thread_fiber == __main_fiber) {
			__thread_fiber = NULL;
		}
		__main_fiber = NULL;
	}
}
/*******************************************************************************
**
** Function        epilog_wait_timeout
**
** Description     Timeout thread of epilog watchdog timer
**
** Returns         None
**
*******************************************************************************/
static void epilog_wait_timeout(UNUSED_ATTR union sigval arg)
{
    ALOGI("...epilog_wait_timeout...");

    thread_free(hc_cb.worker_thread);

    pthread_mutex_lock(&hc_cb.worker_thread_lock);
    hc_cb.worker_thread = NULL;
    pthread_mutex_unlock(&hc_cb.worker_thread_lock);
}
LIBIMOBILEDEVICE_API np_error_t np_client_free(np_client_t client)
{
	plist_t dict;
	property_list_service_client_t parent;

	if (!client)
		return NP_E_INVALID_ARG;

	dict = plist_new_dict();
	plist_dict_set_item(dict,"Command", plist_new_string("Shutdown"));
	property_list_service_send_xml_plist(client->parent, dict);
	plist_free(dict);

	parent = client->parent;
	/* notifies the client->notifier thread that it should terminate */
	client->parent = NULL;

	if (client->notifier) {
		debug_info("joining np callback");
		thread_join(client->notifier);
		thread_free(client->notifier);
		client->notifier = (thread_t)NULL;
	} else {
		dict = NULL;
		property_list_service_receive_plist(parent, &dict);
		if (dict) {
#ifndef STRIP_DEBUG_CODE
			char *cmd_value = NULL;
			plist_t cmd_value_node = plist_dict_get_item(dict, "Command");
			if (plist_get_node_type(cmd_value_node) == PLIST_STRING) {
				plist_get_string_val(cmd_value_node, &cmd_value);
			}
			if (cmd_value && !strcmp(cmd_value, "ProxyDeath")) {
				// this is the expected answer
			} else {
				debug_info("Did not get ProxyDeath but:");
				debug_plist(dict);
			}
			if (cmd_value) {
				free(cmd_value);
			}
#endif
			plist_free(dict);
		}
	}

	property_list_service_client_free(parent);

	mutex_destroy(&client->mutex);
	free(client);

	return NP_E_SUCCESS;
}
Exemplo n.º 12
0
void thread_delete(struct thread *t) {
	static struct thread *zombie = NULL;

	assert(t);
	assert(t->state & TS_EXITED);

	task_thread_unregister(t->task, t);
	thread_local_free(t);

	if (zombie) {
		thread_free(zombie);
	}

	if (t != thread_self()) {
		assert(!t->schedee.active);
		assert(!t->schedee.ready);
		thread_free(t);
		zombie = NULL;
	} else {
		zombie = t;
	}
}
Exemplo n.º 13
0
void
destroy_xshm_image (Display *dpy, XImage *image, XShmSegmentInfo *shm_info)
{
#ifdef HAVE_XSHM_EXTENSION
  if (shm_info->shmid == -1) {
#endif /* HAVE_XSHM_EXTENSION */

    /* Don't let XDestroyImage free image->data. */
    thread_free (image->data);
    image->data = NULL;
    XDestroyImage (image);
    return;

#ifdef HAVE_XSHM_EXTENSION
  }

  Status status;

  CATCH_X_ERROR(dpy);
  status = XShmDetach (dpy, shm_info);
  UNCATCH_X_ERROR(dpy);
  if (shm_got_x_error)
    status = False;
  if (!status)
    fprintf (stderr, "%s: XShmDetach failed!\n", progname);
#ifdef DEBUG
  else
    fprintf (stderr, "%s: XShmDetach(dpy, shm_info) ==> True\n", progname);
#endif

  XDestroyImage (image);
  XSync(dpy, False);

  status = shmdt (shm_info->shmaddr);

  if (status != 0)
    {
      char buf[1024];
      sprintf (buf, "%s: shmdt(0x%lx) failed", progname,
               (unsigned long) shm_info->shmaddr);
      perror(buf);
    }
#ifdef DEBUG
  else
    fprintf (stderr, "%s: shmdt(shm_info->shmaddr) ==> 0\n", progname);
#endif

  XSync(dpy, False);

#endif /* HAVE_XSHM_EXTENSION */
}
Exemplo n.º 14
0
void btif_sock_cleanup(void) {
  if (thread_handle == -1)
    return;

  thread_stop(thread);
  thread_join(thread);
  btsock_thread_exit(thread_handle);
  btsock_rfc_cleanup();
  btsock_sco_cleanup();
  btsock_l2cap_cleanup();
  thread_free(thread);
  thread_handle = -1;
  thread = NULL;
}
Exemplo n.º 15
0
bt_status_t btif_sock_init(void) {
  assert(thread_handle == -1);
  assert(thread == NULL);

  btsock_thread_init();
  thread_handle = btsock_thread_create(btsock_signaled, NULL);
  if (thread_handle == -1) {
    LOG_ERROR("%s unable to create btsock_thread.", __func__);
    goto error;
  }

  bt_status_t status = btsock_rfc_init(thread_handle);
  if (status != BT_STATUS_SUCCESS) {
    LOG_ERROR("%s error initializing RFCOMM sockets: %d", __func__, status);
    goto error;
  }

  status = btsock_l2cap_init(thread_handle);
  if (status != BT_STATUS_SUCCESS) {
    LOG_ERROR("%s error initializing L2CAP sockets: %d", __func__, status);
    goto error;
  }

  thread = thread_new("btif_sock");
  if (!thread) {
    LOG_ERROR("%s error creating new thread.", __func__);
    btsock_rfc_cleanup();
    goto error;
  }

  status = btsock_sco_init(thread);
  if (status != BT_STATUS_SUCCESS) {
    LOG_ERROR("%s error initializing SCO sockets: %d", __func__, status);
    btsock_rfc_cleanup();
    goto error;
  }

  return BT_STATUS_SUCCESS;

error:;
  thread_free(thread);
  thread = NULL;
  if (thread_handle != -1)
    btsock_thread_exit(thread_handle);
  thread_handle = -1;
  return BT_STATUS_FAIL;
}
// Closes the interface.
// This routine is not thread safe.
static void cleanup(void)
{
    if (has_cleaned_up) {
        ALOGW("%s Already cleaned up for this session\n", __func__);
        return;
    }

    BTHCDBG("cleanup");

    if (hc_cb.worker_thread)
    {
        if (fwcfg_acked)
        {
            epilog_wait_timer();
            // Stop reading thread
            userial_close_reader();

            thread_post(hc_cb.worker_thread, event_epilog, NULL);
        }
        thread_free(hc_cb.worker_thread);

        pthread_mutex_lock(&hc_cb.worker_thread_lock);
        hc_cb.worker_thread = NULL;
        pthread_mutex_unlock(&hc_cb.worker_thread_lock);

        if (hc_cb.epilog_timer_created)
        {
            timer_delete(hc_cb.epilog_timer_id);
            hc_cb.epilog_timer_created = false;
        }
    }
    BTHCDBG("%s Finalizing cleanup\n", __func__);

    lpm_cleanup();
    userial_close();
    p_hci_if->cleanup();
    utils_cleanup();

    set_power(BT_VND_PWR_OFF);
    vendor_close();

    pthread_mutex_destroy(&hc_cb.worker_thread_lock);

    fwcfg_acked = false;
    bt_hc_cbacks = NULL;
    has_cleaned_up = true;
}
Exemplo n.º 17
0
/*
 * UMA should ensure that this function is never called.
 * Freeing a proc structure would violate type stability.
 */
static void
proc_fini(void *mem, int size)
{
#ifdef notnow
	struct proc *p;

	p = (struct proc *)mem;
	EVENTHANDLER_INVOKE(process_fini, p);
	pstats_free(p->p_stats);
	thread_free(FIRST_THREAD_IN_PROC(p));
	mtx_destroy(&p->p_mtx);
	if (p->p_ksi != NULL)
		ksiginfo_free(p->p_ksi);
#else
	panic("proc reclaimed");
#endif
}
Exemplo n.º 18
0
static future_t *shut_down() {
  LOG_INFO(LOG_TAG, "%s", __func__);

  hci_inject->close();

  if (thread) {
    if (firmware_is_configured) {
      non_repeating_timer_restart(epilog_timer);
      thread_post(thread, event_epilog, NULL);
    } else {
      thread_stop(thread);
    }

    thread_join(thread);
  }

  fixed_queue_free(command_queue, buffer_allocator->free);
  fixed_queue_free(packet_queue, buffer_allocator->free);
  list_free(commands_pending_response);

  pthread_mutex_destroy(&commands_pending_response_lock);

  packet_fragmenter->cleanup();

  non_repeating_timer_free(epilog_timer);
  non_repeating_timer_free(command_response_timer);
  non_repeating_timer_free(startup_timer);

  epilog_timer = NULL;
  command_response_timer = NULL;

  low_power_manager->cleanup();
  hal->close();

  // Turn off the chip
  int power_state = BT_VND_PWR_OFF;
  vendor->send_command(VENDOR_CHIP_POWER_CONTROL, &power_state);
  vendor->close();

  thread_free(thread);
  thread = NULL;
  firmware_is_configured = false;

  return NULL;
}
Exemplo n.º 19
0
LIBIMOBILEDEVICE_API instproxy_error_t instproxy_client_free(instproxy_client_t client)
{
	if (!client)
		return INSTPROXY_E_INVALID_ARG;

	property_list_service_client_free(client->parent);
	client->parent = NULL;
	if (client->receive_status_thread) {
		debug_info("joining receive_status_thread");
		thread_join(client->receive_status_thread);
		thread_free(client->receive_status_thread);
		client->receive_status_thread = (thread_t)NULL;
	}
	mutex_destroy(&client->mutex);
	free(client);

	return INSTPROXY_E_SUCCESS;
}
Exemplo n.º 20
0
void alarm_cleanup(void) {
  // If lazy_initialize never ran there is nothing to do
  if (!alarms)
    return;

  callback_thread_active = false;
  semaphore_post(alarm_expired);
  thread_free(callback_thread);
  callback_thread = NULL;

  semaphore_free(alarm_expired);
  alarm_expired = NULL;
  timer_delete(&timer);
  list_free(alarms);
  alarms = NULL;

  pthread_mutex_destroy(&monitor);
}
Exemplo n.º 21
0
char PICLANG_save(char saved_status)
{
  if(curr_process.page_size == 0)
    return PICLANG_NO_SUCH_PROGRAM;

  curr_process.status = saved_status;
  SRAM_write(picos_processes[picos_curr_process].addr,&curr_process,PCB_SIZE);
  
  if(saved_status == PICLANG_SUSPENDED)
    thread_suspend(picos_curr_process);
  else
    {
      PAGE_free(picos_curr_process);
      thread_free(picos_curr_process);
    }

  PICLANG_init();

  return 0;

}
Exemplo n.º 22
0
void* thread_realloc(void* addr, size_t size)
{
    if (addr == NULL) {
        return thread_alloc(size);
    }
    alloc_block_header* blk = (alloc_block_header*)addr - 1;
    size_t new_size = ((size + BLOCK_ALIGNMENT-1) & ~(BLOCK_ALIGNMENT-1)) + sizeof(alloc_block_header);
    if (blk->size >= new_size) {
        return addr;
    }
    if (blk->size > MAX_BLOCK_SIZE) {
        blk = (alloc_block_header*)realloc(blk, new_size);
        blk->size = new_size;
        return (alloc_block_header*)blk + 1;
    } else {
        void* new_addr = thread_alloc(size);
        memcpy(new_addr, addr, blk->size - sizeof(alloc_block_header));
        thread_free(addr);
        return new_addr;
    }
}
Exemplo n.º 23
0
void eager_reader_free(eager_reader_t *reader) {
  if (!reader)
    return;

  eager_reader_unregister(reader);

  // Only unregister from the input if we actually did register
  if (reader->inbound_read_object)
    reactor_unregister(reader->inbound_read_object);

  if (reader->bytes_available_fd != INVALID_FD)
    close(reader->bytes_available_fd);

  // Free the current buffer, because it's not in the queue
  // and won't be freed below
  if (reader->current_buffer)
    reader->allocator->free(reader->current_buffer);

  fixed_queue_free(reader->buffers, reader->allocator->free);
  thread_free(reader->inbound_read_thread);
  osi_free(reader);
}
Exemplo n.º 24
0
Arquivo: linux.c Projeto: Laukien/test
int main() {
	THREAD *t = thread_new();
	thread_setFunction(t, sub, NULL);
	thread_run(t);

	int i;
	for (i = 0; i < 10; ++i) {
		if (thread_isRunning(t)) {
			printf ("Thread 1 is still running\n");
			sleep(1);
		}
	}

	thread_wait(t);

	printf("Thread 1 has the status %d\n", thread_getStatus(t));

	printf("Thread 1 has the exit-code %d\n", thread_getExit(t));

	thread_free(t);
	return EXIT_SUCCESS;
}
Exemplo n.º 25
0
void
thread_delete(struct thread *thread)
{
    struct pd *pd;
#if defined(CONFIG_SESSION)
    struct session_p_node *sd;
#endif
    pd = thread->owner;
    (void)L4_ThreadControl(thread->id,
                           L4_nilspace,
                           L4_nilthread, L4_nilthread, L4_nilthread, 0, NULL);
    thread_free(thread->id);

    if (
#if defined(CONFIG_EAS)
        thread->eas == NULL &&
#endif
        thread->utcb != (void *)-1UL) {
        /* free local thread no. */
        bfl_free(pd->local_threadno,
                 ((uintptr_t)thread->utcb -
                  L4_Address(pd->space.utcb_area)) >> L4_GetUtcbBits());
    }
Exemplo n.º 26
0
static void
thread_exit(void *dcontext)
{
    fuzz_pass_context_t *fp = (fuzz_pass_context_t *) drmgr_get_tls_field(dcontext,
                                                                          tls_idx_fuzzer);

    /* crash is indicated by aborted fuzz targets, even if the app did a hard exit() */
    if (fp->live_targets != NULL) {
        if (callbacks->crash_thread_event != NULL) {
            /* There may be targets already captured by a fault event. If not, and if fuzz
             * targets were evidently aborted, then make them available in an iterator.
             */
            if (fp->thread_state->targets == NULL && fp->live_targets != NULL)
                fp->thread_state->targets = create_target_iterator(fp);

            callbacks->crash_thread_event(fp, fp->thread_state);
        }
    }

    free_thread_state(fp);
    clear_pass_targets(fp);
    thread_free(dcontext, fp, sizeof(fuzz_pass_context_t), HEAPSTAT_MISC);
}
int test_scheduler()
{
	shared_counter = 0;
	struct thread_t* threads[5];
	scheduler_begin(2);
	threads[0] = thread_fork(increment, (void*)"1");
	threads[1] = thread_fork(increment, (void*)"2");	
	threads[2] = thread_fork(increment, (void*)"3");
	threads[3] = thread_fork(increment, (void*)"4");
	threads[4] = thread_fork(increment, (void*)"5");
	scheduler_end(); 
	//free threads' memories
	int i;
	for (i=0;i<5;i++)
	{
		thread_free(threads[i]);
	}
	//check if the result is correct
	if (shared_counter != 100*5)
	{		
		return -1;
	}			
	return 0;
}
LIBIMOBILEDEVICE_API np_error_t np_set_notify_callback( np_client_t client, np_notify_cb_t notify_cb, void *user_data )
{
	if (!client)
		return NP_E_INVALID_ARG;

	np_error_t res = NP_E_UNKNOWN_ERROR;

	np_lock(client);
	if (client->notifier) {
		debug_info("callback already set, removing");
		property_list_service_client_t parent = client->parent;
		client->parent = NULL;
		thread_join(client->notifier);
		thread_free(client->notifier);
		client->notifier = (thread_t)NULL;
		client->parent = parent;
	}

	if (notify_cb) {
		struct np_thread *npt = (struct np_thread*)malloc(sizeof(struct np_thread));
		if (npt) {
			npt->client = client;
			npt->cbfunc = notify_cb;
			npt->user_data = user_data;

			if (thread_new(&client->notifier, np_notifier, npt) == 0) {
				res = NP_E_SUCCESS;
			}
		}
	} else {
		debug_info("no callback set");
	}
	np_unlock(client);

	return res;
}
Exemplo n.º 29
0
void setter_remove(setter_t setter){
    thread_free(setter->th);
    free(setter);
}
Exemplo n.º 30
0
static int
create_thread(struct thread *td, mcontext_t *ctx,
	    void (*start_func)(void *), void *arg,
	    char *stack_base, size_t stack_size,
	    char *tls_base,
	    long *child_tid, long *parent_tid,
	    int flags, struct rtprio *rtp)
{
	stack_t stack;
	struct thread *newtd;
	struct proc *p;
	int error;

	p = td->td_proc;

	/* Have race condition but it is cheap. */
	if (p->p_numthreads >= max_threads_per_proc) {
		++max_threads_hits;
		return (EPROCLIM);
	}

	if (rtp != NULL) {
		switch(rtp->type) {
		case RTP_PRIO_REALTIME:
		case RTP_PRIO_FIFO:
			/* Only root can set scheduler policy */
			if (priv_check(td, PRIV_SCHED_SETPOLICY) != 0)
				return (EPERM);
			if (rtp->prio > RTP_PRIO_MAX)
				return (EINVAL);
			break;
		case RTP_PRIO_NORMAL:
			rtp->prio = 0;
			break;
		default:
			return (EINVAL);
		}
	}

#ifdef RACCT
	PROC_LOCK(td->td_proc);
	error = racct_add(p, RACCT_NTHR, 1);
	PROC_UNLOCK(td->td_proc);
	if (error != 0)
		return (EPROCLIM);
#endif

	/* Initialize our td */
	newtd = thread_alloc(0);
	if (newtd == NULL) {
		error = ENOMEM;
		goto fail;
	}

	cpu_set_upcall(newtd, td);

	/*
	 * Try the copyout as soon as we allocate the td so we don't
	 * have to tear things down in a failure case below.
	 * Here we copy out tid to two places, one for child and one
	 * for parent, because pthread can create a detached thread,
	 * if parent wants to safely access child tid, it has to provide 
	 * its storage, because child thread may exit quickly and
	 * memory is freed before parent thread can access it.
	 */
	if ((child_tid != NULL &&
	    suword_lwpid(child_tid, newtd->td_tid)) ||
	    (parent_tid != NULL &&
	    suword_lwpid(parent_tid, newtd->td_tid))) {
		thread_free(newtd);
		error = EFAULT;
		goto fail;
	}

	bzero(&newtd->td_startzero,
	    __rangeof(struct thread, td_startzero, td_endzero));
	bcopy(&td->td_startcopy, &newtd->td_startcopy,
	    __rangeof(struct thread, td_startcopy, td_endcopy));
	newtd->td_proc = td->td_proc;
	newtd->td_ucred = crhold(td->td_ucred);

	if (ctx != NULL) { /* old way to set user context */
		error = set_mcontext(newtd, ctx);
		if (error != 0) {
			thread_free(newtd);
			crfree(td->td_ucred);
			goto fail;
		}
	} else {
		/* Set up our machine context. */
		stack.ss_sp = stack_base;
		stack.ss_size = stack_size;
		/* Set upcall address to user thread entry function. */
		cpu_set_upcall_kse(newtd, start_func, arg, &stack);
		/* Setup user TLS address and TLS pointer register. */
		error = cpu_set_user_tls(newtd, tls_base);
		if (error != 0) {
			thread_free(newtd);
			crfree(td->td_ucred);
			goto fail;
		}
	}

	PROC_LOCK(td->td_proc);
	td->td_proc->p_flag |= P_HADTHREADS;
	thread_link(newtd, p); 
	bcopy(p->p_comm, newtd->td_name, sizeof(newtd->td_name));
	thread_lock(td);
	/* let the scheduler know about these things. */
	sched_fork_thread(td, newtd);
	thread_unlock(td);
	if (P_SHOULDSTOP(p))
		newtd->td_flags |= TDF_ASTPENDING | TDF_NEEDSUSPCHK;
	PROC_UNLOCK(p);

	tidhash_add(newtd);

	thread_lock(newtd);
	if (rtp != NULL) {
		if (!(td->td_pri_class == PRI_TIMESHARE &&
		      rtp->type == RTP_PRIO_NORMAL)) {
			rtp_to_pri(rtp, newtd);
			sched_prio(newtd, newtd->td_user_pri);
		} /* ignore timesharing class */
	}
	TD_SET_CAN_RUN(newtd);
	sched_add(newtd, SRQ_BORING);
	thread_unlock(newtd);

	return (0);

fail:
#ifdef RACCT
	PROC_LOCK(p);
	racct_sub(p, RACCT_NTHR, 1);
	PROC_UNLOCK(p);
#endif
	return (error);
}