Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
miniaudio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
miniaudio
Commits
71185464
Commit
71185464
authored
Jul 17, 2021
by
David Reid
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move ma_fence into the main library.
parent
cc2b1485
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
176 additions
and
149 deletions
+176
-149
miniaudio.h
miniaudio.h
+176
-0
research/miniaudio_engine.h
research/miniaudio_engine.h
+0
-149
No files found.
miniaudio.h
View file @
71185464
...
...
@@ -5815,6 +5815,38 @@ MA_API ma_result ma_event_signal(ma_event* pEvent);
#endif /* MA_NO_THREADING */
/*
Fence
=====
This locks while the counter is larger than 0. Counter can be incremented and decremented by any
thread, but care needs to be taken when waiting. It is possible for one thread to acquire the
fence just as another thread returns from ma_fence_wait().
The idea behind a fence is to allow you to wait for a group of operations to complete. When an
operation starts, the counter is incremented which locks the fence. When the operation completes,
the fence will be released which decrements the counter. ma_fence_wait() will block until the
counter hits zero.
If threading is disabled, ma_fence_wait() will spin on the counter.
*/
typedef struct
{
#ifndef MA_NO_THREADING
ma_event e;
#endif
ma_uint32 counter;
} ma_fence;
MA_API ma_result ma_fence_init(ma_fence* pFence);
MA_API void ma_fence_uninit(ma_fence* pFence);
MA_API ma_result ma_fence_acquire(ma_fence* pFence); /* Increment counter. */
MA_API ma_result ma_fence_release(ma_fence* pFence); /* Decrement counter. */
MA_API ma_result ma_fence_wait(ma_fence* pFence); /* Wait for counter to reach 0. */
/************************************************************************************************************************************************************
Utiltities
...
...
@@ -11365,6 +11397,150 @@ MA_API ma_result ma_semaphore_release(ma_semaphore* pSemaphore)
#define MA_FENCE_COUNTER_MAX 0x7FFFFFFF
MA_API ma_result ma_fence_init(ma_fence* pFence)
{
if (pFence == NULL) {
return MA_INVALID_ARGS;
}
MA_ZERO_OBJECT(pFence);
pFence->counter = 0;
#ifndef MA_NO_THREADING
{
ma_result result;
result = ma_event_init(&pFence->e);
if (result != MA_SUCCESS) {
return result;
}
}
#endif
return MA_SUCCESS;
}
MA_API void ma_fence_uninit(ma_fence* pFence)
{
if (pFence == NULL) {
return;
}
#ifndef MA_NO_THREADING
{
ma_event_uninit(&pFence->e);
}
#endif
MA_ZERO_OBJECT(pFence);
}
MA_API ma_result ma_fence_acquire(ma_fence* pFence)
{
if (pFence == NULL) {
return MA_INVALID_ARGS;
}
for (;;) {
ma_uint32 oldCounter = c89atomic_load_32(&pFence->counter);
ma_uint32 newCounter = oldCounter + 1;
/* Make sure we're not about to exceed our maximum value. */
if (newCounter > MA_FENCE_COUNTER_MAX) {
MA_ASSERT(MA_FALSE);
return MA_OUT_OF_RANGE;
}
if (c89atomic_compare_exchange_weak_32(&pFence->counter, &oldCounter, newCounter)) {
return MA_SUCCESS;
} else {
if (oldCounter == MA_FENCE_COUNTER_MAX) {
MA_ASSERT(MA_FALSE);
return MA_OUT_OF_RANGE; /* The other thread took the last available slot. Abort. */
}
}
}
/* Should never get here. */
/*return MA_SUCCESS;*/
}
MA_API ma_result ma_fence_release(ma_fence* pFence)
{
if (pFence == NULL) {
return MA_INVALID_ARGS;
}
for (;;) {
ma_uint32 oldCounter = c89atomic_load_32(&pFence->counter);
ma_uint32 newCounter = oldCounter - 1;
if (oldCounter == 0) {
MA_ASSERT(MA_FALSE);
return MA_INVALID_OPERATION; /* Acquire/release mismatch. */
}
if (c89atomic_compare_exchange_weak_32(&pFence->counter, &oldCounter, newCounter)) {
#ifndef MA_NO_THREADING
{
if (newCounter == 0) {
ma_event_signal(&pFence->e); /* <-- ma_fence_wait() will be waiting on this. */
}
}
#endif
return MA_SUCCESS;
} else {
if (oldCounter == 0) {
MA_ASSERT(MA_FALSE);
return MA_INVALID_OPERATION; /* Another thread has taken the 0 slot. Acquire/release mismatch. */
}
}
}
/* Should never get here. */
/*return MA_SUCCESS;*/
}
MA_API ma_result ma_fence_wait(ma_fence* pFence)
{
if (pFence == NULL) {
return MA_INVALID_ARGS;
}
for (;;) {
ma_uint32 counter;
counter = c89atomic_load_32(&pFence->counter);
if (counter == 0) {
/*
Counter has hit zero. By the time we get here some other thread may have acquired the
fence again, but that is where the caller needs to take care with how they se the fence.
*/
return MA_SUCCESS;
}
/* Getting here means the counter is > 0. We'll need to wait for something to happen. */
#ifndef MA_NO_THREADING
{
ma_result result;
result = ma_event_wait(&pFence->e);
if (result != MA_SUCCESS) {
return result;
}
}
#endif
}
/* Should never get here. */
/*return MA_INVALID_OPERATION;*/
}
/************************************************************************************************************************************************************
*************************************************************************************************************************************************************
research/miniaudio_engine.h
View file @
71185464
...
...
@@ -1148,29 +1148,7 @@ MA_API ma_result ma_slot_allocator_free(ma_slot_allocator* pAllocator, ma_uint64
/*
Fence
=====
This locks while the counter is larger than 0. Counter can be incremented and decremented by any
thread, but care needs to be taken when waiting. It is possible for one thread to acquire the
fence just as another thread returns from ma_fence_wait().
The idea behind a fence is to allow you to wait for a group of operations to complete. When an
operation starts, the counter is incremented which locks the fence. When the operation completes,
the fence will be released which decrements the counter. ma_fence_wait() will block until the
counter hits zero.
*/
typedef
struct
{
ma_event
e
;
ma_uint32
counter
;
}
ma_fence
;
MA_API
ma_result
ma_fence_init
(
ma_fence
*
pFence
);
MA_API
void
ma_fence_uninit
(
ma_fence
*
pFence
);
MA_API
ma_result
ma_fence_acquire
(
ma_fence
*
pFence
);
/* Increment counter. */
MA_API
ma_result
ma_fence_release
(
ma_fence
*
pFence
);
/* Decrement counter. */
MA_API
ma_result
ma_fence_wait
(
ma_fence
*
pFence
);
/* Wait for counter to reach 0. */
...
...
@@ -5123,133 +5101,6 @@ MA_API ma_result ma_slot_allocator_free(ma_slot_allocator* pAllocator, ma_uint64
#define MA_FENCE_COUNTER_MAX 0x7FFFFFFF
MA_API
ma_result
ma_fence_init
(
ma_fence
*
pFence
)
{
ma_result
result
;
if
(
pFence
==
NULL
)
{
return
MA_INVALID_ARGS
;
}
MA_ZERO_OBJECT
(
pFence
);
pFence
->
counter
=
0
;
result
=
ma_event_init
(
&
pFence
->
e
);
if
(
result
!=
MA_SUCCESS
)
{
return
result
;
}
return
MA_SUCCESS
;
}
MA_API
void
ma_fence_uninit
(
ma_fence
*
pFence
)
{
if
(
pFence
==
NULL
)
{
return
;
}
ma_event_uninit
(
&
pFence
->
e
);
MA_ZERO_OBJECT
(
pFence
);
}
MA_API
ma_result
ma_fence_acquire
(
ma_fence
*
pFence
)
{
if
(
pFence
==
NULL
)
{
return
MA_INVALID_ARGS
;
}
for
(;;)
{
ma_uint32
oldCounter
=
c89atomic_load_32
(
&
pFence
->
counter
);
ma_uint32
newCounter
=
oldCounter
+
1
;
/* Make sure we're not about to exceed our maximum value. */
if
(
newCounter
>
MA_FENCE_COUNTER_MAX
)
{
MA_ASSERT
(
MA_FALSE
);
return
MA_OUT_OF_RANGE
;
}
if
(
c89atomic_compare_exchange_weak_32
(
&
pFence
->
counter
,
&
oldCounter
,
newCounter
))
{
return
MA_SUCCESS
;
}
else
{
if
(
oldCounter
==
MA_FENCE_COUNTER_MAX
)
{
MA_ASSERT
(
MA_FALSE
);
return
MA_OUT_OF_RANGE
;
/* The other thread took the last available slot. Abort. */
}
}
}
/* Should never get here. */
/*return MA_SUCCESS;*/
}
MA_API
ma_result
ma_fence_release
(
ma_fence
*
pFence
)
{
if
(
pFence
==
NULL
)
{
return
MA_INVALID_ARGS
;
}
for
(;;)
{
ma_uint32
oldCounter
=
c89atomic_load_32
(
&
pFence
->
counter
);
ma_uint32
newCounter
=
oldCounter
-
1
;
if
(
oldCounter
==
0
)
{
MA_ASSERT
(
MA_FALSE
);
return
MA_INVALID_OPERATION
;
/* Acquire/release mismatch. */
}
if
(
c89atomic_compare_exchange_weak_32
(
&
pFence
->
counter
,
&
oldCounter
,
newCounter
))
{
if
(
newCounter
==
0
)
{
ma_event_signal
(
&
pFence
->
e
);
/* <-- ma_fence_wait() will be waiting on this. */
}
return
MA_SUCCESS
;
}
else
{
if
(
oldCounter
==
0
)
{
MA_ASSERT
(
MA_FALSE
);
return
MA_INVALID_OPERATION
;
/* Another thread has taken the 0 slot. Acquire/release mismatch. */
}
}
}
/* Should never get here. */
/*return MA_SUCCESS;*/
}
MA_API
ma_result
ma_fence_wait
(
ma_fence
*
pFence
)
{
if
(
pFence
==
NULL
)
{
return
MA_INVALID_ARGS
;
}
for
(;;)
{
ma_result
result
;
ma_uint32
counter
;
counter
=
c89atomic_load_32
(
&
pFence
->
counter
);
if
(
counter
==
0
)
{
/*
Counter has hit zero. By the time we get here some other thread may have acquired the
fence again, but that is where the caller needs to take care with how they se the fence.
*/
return
MA_SUCCESS
;
}
/* Getting here means the counter is > 0. We'll need to wait for something to happen. */
result
=
ma_event_wait
(
&
pFence
->
e
);
if
(
result
!=
MA_SUCCESS
)
{
return
result
;
}
}
/* Should never get here. */
/*return MA_INVALID_OPERATION;*/
}
MA_API
ma_result
ma_async_notification_signal
(
ma_async_notification
*
pNotification
)
{
ma_async_notification_callbacks
*
pNotificationCallbacks
=
(
ma_async_notification_callbacks
*
)
pNotification
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment