---
name: "sx_try_xlock"
section: "9"
platform: "linux"
package: "freebsd-manpages"
version: "6.0-5"
release: "Debian 4.0 (Etch)"
platforms: ["linux", "freebsd"]
url: "https://new.carta.tech/sx_try_xlock"
---

# sx\_try\_xlock(9)

kernel shared/exclusive lock

## NAME

**sx**, **sx\_init**, **sx\_destroy**, **sx\_slock**, **sx\_xlock**, **sx\_try\_slock**, **sx\_try\_xlock**, **sx\_sunlock**, **sx\_xunlock**, **sx\_try\_upgrade**, **sx\_downgrade**, **sx\_assert**, **sx\_unlock**, **SX\_SYSINIT** – kernel shared/exclusive lock

## SYNOPSIS

**#include \<sys/param.h\>**

**#include \<sys/lock.h\>**

**#include \<sys/sx.h\>**

*void*\

**sx\_init**(*struct sx \*sx*, *const char \*description*);

*void*\

**sx\_destroy**(*struct sx \*sx*);

*void*\

**sx\_slock**(*struct sx \*sx*);

*void*\

**sx\_xlock**(*struct sx \*sx*);

*int*\

**sx\_try\_slock**(*struct sx \*sx*);

*int*\

**sx\_try\_xlock**(*struct sx \*sx*);

*void*\

**sx\_sunlock**(*struct sx \*sx*);

*void*\

**sx\_xunlock**(*struct sx \*sx*);

*int*\

**sx\_try\_upgrade**(*struct sx \*sx*);

*void*\

**sx\_downgrade**(*struct sx \*sx*);

*void*\

**sx\_assert**(*struct sx \*sx*, *int what*);

### Nm Ss utility macros

**sx\_unlock**(*struct sx \*sx*);

**SX\_SYSINIT**(*name*, *struct sx \*sx*, *const char \*description*);

### Kernel options

**options INVARIANTS** **options INVARIANT\_SUPPORT**

## DESCRIPTION

Shared/exclusive locks are used to protect data that are read far more often than they are written. Mutexes are inherently more efficient than shared/exclusive locks, so shared/exclusive locks should be used prudently.

Shared/exclusive locks are created with **sx\_init**(), where *sx* is a pointer to space for a *struct* *sx*, and *description* is a pointer to a null-terminated character string that describes the shared/exclusive lock. Shared/exclusive locks are destroyed with **sx\_destroy**(). Threads acquire and release a shared lock by calling **sx\_slock**() or **sx\_try\_slock**() and **sx\_sunlock**() or **sx\_unlock**(). Threads acquire and release an exclusive lock by calling **sx\_xlock**() or **sx\_try\_xlock**() and **sx\_xunlock**() or **sx\_unlock**(). A thread can attempt to upgrade a currently held shared lock to an exclusive lock by calling **sx\_try\_upgrade**(). A thread that has an exclusive lock can downgrade it to a shared lock by calling **sx\_downgrade**().

**sx\_try\_slock**() and **sx\_try\_xlock**() will return 0 if the shared/exclusive lock cannot be acquired immediately; otherwise the shared/exclusive lock will be acquired and a non-zero value will be returned.

**sx\_try\_upgrade**() will return 0 if the shared lock cannot be upgraded to an exclusive lock immediately; otherwise the exclusive lock will be acquired and a non-zero value will be returned.

When compiled with **options INVARIANTS** and **options INVARIANT\_SUPPORT**, the **sx\_assert**() function tests *sx* for the assertions specified in *what*, and panics if they are not met. The following assertions are supported:

- SX\_LOCKED

  Assert that the current thread has either a shared or an exclusive lock on the *sx* lock pointed to by the first argument.

- SX\_SLOCKED

  Assert that the current thread has a shared lock on the *sx* lock pointed to by the first argument.

- SX\_XLOCKED

  Assert that the current thread has an exclusive lock on the *sx* lock pointed to by the first argument.

- SX\_UNLOCKED

  Assert that the current thread has no lock on the *sx* lock pointed to by the first argument.

For ease of programming, **sx\_unlock**() is provided as a macro frontend to the respective functions, **sx\_sunlock**() and **sx\_xunlock**(). Algorithms that are aware of what state the lock is in should use either of the two specific functions for a minor performance benefit.

The **SX\_SYSINIT**() macro is used to generate a call to the **sx\_sysinit**() routine at system startup in order to initialize a given *sx* lock. The parameters are the same as **sx\_init**() but with an additional argument, *name*, that is used in generating unique variable names for the related structures associated with the lock and the sysinit routine.

A thread may not hold both a shared lock and an exclusive lock on the same lock simultaneously; attempting to do so will result in deadlock.

## CONTEXT

A thread may hold a shared or exclusive lock on an **sx** lock while sleeping. As a result, an **sx** lock may not be acquired while holding a mutex. Otherwise, if one thread slept while holding an **sx** lock while another thread blocked on the same **sx** lock after acquiring a mutex, then the second thread would effectively end up sleeping while holding a mutex, which is not allowed.

## SEE ALSO

[condvar(9)](/condvar/9.md), [mtx\_pool(9)](/mtx_pool/9.md), [mutex(9)](/mutex/9.md), [panic(9)](/panic/9.md), [sema(9)](/sema/9.md)

## BUGS

Currently there is no way to assert that a lock is not held. This is not possible in the non-WITNESS case for asserting that this thread does not hold a shared lock. In the non-WITNESS case, the SX\_LOCKED and SX\_SLOCKED assertions merely check that some thread holds a shared lock. They do not ensure that the current thread holds a shared lock.
