TCP: post buffer semaphore before re-acquiring both
TCP uses two semaphores for buffers, one for the entire buffer pool, and one for the number of allowed buffers for readahead. To avoid double taking a semaphore under heavy load, release the semaphore after waiting before trying to acquire both again.
This commit is contained in:
parent
4875c6bbe3
commit
e221777a7a
@ -121,16 +121,45 @@ static FAR struct iob_s *iob_allocwait(bool throttled)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
ret = sem_wait(sem);
|
ret = sem_wait(sem);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
int errcode = get_errno();
|
||||||
|
|
||||||
/* When we wake up from wait, an I/O buffer was returned to
|
/* EINTR is not an error! EINTR simply means that we were
|
||||||
* the free list. However, if there are concurrent allocations
|
* awakened by a signal and we should try again.
|
||||||
* from interrupt handling, then I suspect that there is a
|
|
||||||
* race condition. But no harm, we will just wait again in
|
|
||||||
* that case.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (errcode == EINTR)
|
||||||
|
{
|
||||||
|
/* Force a success indication so that we will continue
|
||||||
|
* looping.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (ret == OK && !iob);
|
else
|
||||||
|
{
|
||||||
|
/* When we wake up from wait successfully, an I/O buffer was
|
||||||
|
* returned to the free list. However, if there are concurrent
|
||||||
|
* allocations from interrupt handling, then I suspect that
|
||||||
|
* there is a race condition. But no harm, we will just wait
|
||||||
|
* again in that case.
|
||||||
|
*
|
||||||
|
* We need release our count so that it is available to
|
||||||
|
* iob_tryalloc(), perhaps allowing another thread to take our
|
||||||
|
* count. In that event, iob_tryalloc() will fail above and
|
||||||
|
* we will have to wait again.
|
||||||
|
*
|
||||||
|
* TODO: Consider a design modification to permit us to
|
||||||
|
* complete the allocation without losing our count.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sem_post(sem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (ret == OK && iob == NULL);
|
||||||
|
|
||||||
irqrestore(flags);
|
irqrestore(flags);
|
||||||
return iob;
|
return iob;
|
||||||
|
Loading…
Reference in New Issue
Block a user