---
name: "mtx_unlock"
section: "3"
platform: "freebsd"
package: "base"
version: "16.0-CURRENT-20261027-61c70dc16a79"
release: "FreeBSD 16.0-CURRENT (2026-10-27)"
platforms: ["freebsd"]
url: "https://new.carta.tech/call_once"
---

# mtx\_unlock(3)

C11 threads interface

Part of [call\_once(3)](/call_once/3.md).

## NAME

**call\_once**, **cnd\_broadcast**, **cnd\_destroy**, **cnd\_init**, **cnd\_signal**, **cnd\_timedwait**, **cnd\_wait**, **mtx\_destroy**, **mtx\_init**, **mtx\_lock**, **mtx\_timedlock**, **mtx\_trylock**, **mtx\_unlock**, **thrd\_create**, **thrd\_current**, **thrd\_detach**, **thrd\_equal**, **thrd\_exit**, **thrd\_join**, **thrd\_sleep**, **thrd\_yield**, **tss\_create**, **tss\_delete**, **tss\_get**, **tss\_set** – C11 threads interface

## LIBRARY

library “libstdthreads”

## SYNOPSIS

**#include \<threads.h\>**

*void*\

**call\_once**(*once\_flag \*flag*, *void (\*func)(void)*);

*int*\

**cnd\_broadcast**(*cnd\_t \*cond*);

*void*\

**cnd\_destroy**(*cnd\_t \*cond*);

*int*\

**cnd\_init**(*cnd\_t \*cond*);

*int*\

**cnd\_signal**(*cnd\_t \*cond*);

*int*\

**cnd\_timedwait**(*cnd\_t \* restrict cond*, *mtx\_t \* restrict mtx*, *const struct timespec \* restrict ts*);

*int*\

**cnd\_wait**(*cnd\_t \*cond*, *mtx\_t \*mtx*);

*void*\

**mtx\_destroy**(*mtx\_t \*mtx*);

*int*\

**mtx\_init**(*mtx\_t \*mtx*, *int type*);

*int*\

**mtx\_lock**(*mtx\_t \*mtx*);

*int*\

**mtx\_timedlock**(*mtx\_t \* restrict mtx*, *const struct timespec \* restrict ts*);

*int*\

**mtx\_trylock**(*mtx\_t \*mtx*);

*int*\

**mtx\_unlock**(*mtx\_t \*mtx*);

*int*\

**thrd\_create**(*thrd\_t \*thr*, *int (\*func)(void \*)*, *void \*arg*);

*thrd\_t*\

**thrd\_current**(*void*);

*int*\

**thrd\_detach**(*thrd\_t thr*);

*int*\

**thrd\_equal**(*thrd\_t thr0*, *thrd\_t thr1*);

*\_Noreturn* *void*\

**thrd\_exit**(*int res*);

*int*\

**thrd\_join**(*thrd\_t thr*, *int \*res*);

*int*\

**thrd\_sleep**(*const struct timespec \*duration*, *struct timespec \*remaining*);

*void*\

**thrd\_yield**(*void*);

*int*\

**tss\_create**(*tss\_t \*key*, *void (\*dtor)(void \*)*);

*void*\

**tss\_delete**(*tss\_t key*);

*void* *\**\

**tss\_get**(*tss\_t key*);

*int*\

**tss\_set**(*tss\_t key*, *void \*val*);

## DESCRIPTION

As of ISO/IEC 9899:2011 (“ISO C11”), the C standard includes an API for writing multithreaded applications. Since POSIX.1 already includes a threading API that is used by virtually any multithreaded application, the interface provided by the C standard can be considered superfluous.

In this implementation, the threading interface is therefore implemented as a light-weight layer on top of existing interfaces. The functions to which these routines are mapped, are listed in the following table. Please refer to the documentation of the POSIX equivalent functions for more information.

| | |
| --- | --- |
| *Function* | *POSIX* *equivalent* |
| **call\_once**() | [pthread\_once(3)](/pthread_once/3.md) |
| **cnd\_broadcast**() | [pthread\_cond\_broadcast(3)](/pthread_cond_broadcast/3.md) |
| **cnd\_destroy**() | [pthread\_cond\_destroy(3)](/pthread_cond_destroy/3.md) |
| **cnd\_init**() | [pthread\_cond\_init(3)](/pthread_cond_init/3.md) |
| **cnd\_signal**() | [pthread\_cond\_signal(3)](/pthread_cond_signal/3.md) |
| **cnd\_timedwait**() | [pthread\_cond\_timedwait(3)](/pthread_cond_timedwait/3.md) |
| **cnd\_wait**() | [pthread\_cond\_wait(3)](/pthread_cond_wait/3.md) |
| **mtx\_destroy**() | [pthread\_mutex\_destroy(3)](/pthread_mutex_destroy/3.md) |
| **mtx\_init**() | [pthread\_mutex\_init(3)](/pthread_mutex_init/3.md) |
| **mtx\_lock**() | [pthread\_mutex\_lock(3)](/pthread_mutex_lock/3.md) |
| **mtx\_timedlock**() | [pthread\_mutex\_timedlock(3)](/pthread_mutex_timedlock/3.md) |
| **mtx\_trylock**() | [pthread\_mutex\_trylock(3)](/pthread_mutex_trylock/3.md) |
| **mtx\_unlock**() | [pthread\_mutex\_unlock(3)](/pthread_mutex_unlock/3.md) |
| **thrd\_create**() | [pthread\_create(3)](/pthread_create/3.md) |
| **thrd\_current**() | [pthread\_self(3)](/pthread_self/3.md) |
| **thrd\_detach**() | [pthread\_detach(3)](/pthread_detach/3.md) |
| **thrd\_equal**() | [pthread\_equal(3)](/pthread_equal/3.md) |
| **thrd\_exit**() | [pthread\_exit(3)](/pthread_exit/3.md) |
| **thrd\_join**() | [pthread\_join(3)](/pthread_join/3.md) |
| **thrd\_sleep**() | [nanosleep(2)](/nanosleep/2.md) |
| **thrd\_yield**() | [pthread\_yield(3)](/pthread_yield/3.md) |
| **tss\_create**() | [pthread\_key\_create(3)](/pthread_key_create/3.md) |
| **tss\_delete**() | [pthread\_key\_delete(3)](/pthread_key_delete/3.md) |
| **tss\_get**() | [pthread\_getspecific(3)](/pthread_getspecific/3.md) |
| **tss\_set**() | [pthread\_setspecific(3)](/pthread_setspecific/3.md) |

## DIFFERENCES WITH POSIX EQUIVALENTS

The **thrd\_exit**() function returns an integer value to the thread calling **thrd\_join**(), whereas the **pthread\_exit**() function uses a pointer.

The mutex created by **mtx\_init**() can be of *type* mtx\_plain or mtx\_timed to distinguish between a mutex that supports **mtx\_timedlock**(). This type can be *or'd* with mtx\_recursive to create a mutex that allows recursive acquisition. These properties are normally set using **pthread\_mutex\_init**(*Ns*, *'s*) *attr* parameter.

## RETURN VALUES

If successful, the **cnd\_broadcast**(), **cnd\_init**(), **cnd\_signal**(), **cnd\_timedwait**(), **cnd\_wait**(), **mtx\_init**(), **mtx\_lock**(), **mtx\_timedlock**(), **mtx\_trylock**(), **mtx\_unlock**(), **thrd\_create**(), **thrd\_detach**(), **thrd\_equal**(), **thrd\_join**(), **thrd\_sleep**(), **tss\_create**() and **tss\_set**() functions return thrd\_success. Otherwise an error code will be returned to indicate the error.

The **thrd\_current**() function returns the thread ID of the calling thread.

The **tss\_get**() function returns the thread-specific data value associated with the given *key*. If no thread-specific data value is associated with *key*, then the value NULL is returned.

## ERRORS

The **cnd\_init**() and **thrd\_create**() functions will fail if:

- thrd\_nomem

  The system has insufficient memory.

The **cnd\_timedwait**() and **mtx\_timedlock**() functions will fail if:

- thrd\_timedout

  The system time has reached or exceeded the time specified in *ts* before the operation could be completed.

The **mtx\_trylock**() function will fail if:

- thrd\_busy

  The mutex is already locked.

In all other cases, these functions may fail by returning general error code thrd\_error.

## SEE ALSO

[nanosleep(2)](/nanosleep/2.md), [pthread(3)](/pthread/3.md)

## STANDARDS

These functions are expected to conform to ISO/IEC 9899:2011 (“ISO C11”).

## HISTORY

These functions appeared in FreeBSD 10.0.

## AUTHORS

Ed Schouten ⟨*ed@FreeBSD.org*⟩
