mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 10:51:54 -04:00
Add os_usleep with bounded sleep loop returning on signal interruption and use it in bandwidth limiter
This commit is contained in:
parent
2bf74bc66f
commit
daf713820e
5 changed files with 66 additions and 20 deletions
|
|
@ -42,7 +42,7 @@ void bw_limit(struct snapraid_bw* bw, uint64_t bytes)
|
|||
bw->total += bytes;
|
||||
done = bw->total;
|
||||
|
||||
eta = done * 1000 / bw->limit;
|
||||
eta = (done / bw->limit) * 1000 + (done % bw->limit) * 1000 / bw->limit;
|
||||
|
||||
/*
|
||||
* To prevent accumulating unlimited credit during long pauses
|
||||
|
|
@ -61,10 +61,7 @@ void bw_limit(struct snapraid_bw* bw, uint64_t bytes)
|
|||
#endif
|
||||
|
||||
if (eta > elapsed) {
|
||||
eta -= elapsed;
|
||||
if (eta > 1000)
|
||||
eta = 1000;
|
||||
usleep((unsigned)eta * 1000);
|
||||
os_usleep((eta - elapsed) * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
32
os/mingw.c
32
os/mingw.c
|
|
@ -469,10 +469,10 @@ static int windows_info2stat(const BY_HANDLE_FILE_INFORMATION* info, const FILE_
|
|||
* the nFileIndexHigh and nFileIndexLow members. This API is an extended version
|
||||
* that includes 128-bit file identifiers. If GetFileInformationByHandle returns
|
||||
* FILE_INVALID_FILE_ID, the identifier may only be described in 128 bit form.
|
||||
*
|
||||
*
|
||||
* From Microsoft "[MS-FSCC]: File System Control Codes - 11/21/2025 v60.0 - 6 Appendix B: Product Behavior"
|
||||
* https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/d4bc551b-7aaf-4b4f-ba0e-3a75e7c528f0
|
||||
*
|
||||
*
|
||||
* 64bitFileID Generate Stable Unique
|
||||
* FAT Yes No No
|
||||
* EXFAT Yes No No
|
||||
|
|
@ -492,7 +492,7 @@ static int windows_info2stat(const BY_HANDLE_FILE_INFORMATION* info, const FILE_
|
|||
*
|
||||
* From Microsoft "[MS-FSCC]: File System Control Codes - 11/21/2025 v60.0 - 2.1.9 64-bit file ID"
|
||||
* https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/2d3333fe-fc98-4a6f-98a2-4bb805aff407?utm_source=chatgpt.com
|
||||
*
|
||||
*
|
||||
* A 64-bit file ID value uniquely identifies a file within a given volume. This
|
||||
* identifier is generated and stored by the file system. The identifier SHOULD
|
||||
* be unique to the volume and stable until the file is deleted.
|
||||
|
|
@ -1600,11 +1600,6 @@ unsigned windows_sleep(unsigned seconds)
|
|||
return seconds;
|
||||
}
|
||||
|
||||
void windows_usleep(uint64_t useconds)
|
||||
{
|
||||
Sleep(useconds / 1000);
|
||||
}
|
||||
|
||||
int windows_link(const char* existing, const char* file)
|
||||
{
|
||||
wchar_t conv_buf_file[CONV_MAX];
|
||||
|
|
@ -3458,6 +3453,27 @@ uint64_t os_tick_ms(void)
|
|||
return GetTickCount64();
|
||||
}
|
||||
|
||||
int os_usleep(uint64_t usec)
|
||||
{
|
||||
while (usec > 0) {
|
||||
unsigned chunk = 1000000;
|
||||
if (usec < chunk)
|
||||
chunk = (unsigned)usec;
|
||||
|
||||
if (os_signal_interrupt()) {
|
||||
errno = EINTR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Sleep(chunk / 1000);
|
||||
|
||||
usec -= chunk;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void os_privileges_acquire(void)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -156,8 +156,6 @@ wchar_t* u8tou16_mayfail(wchar_t* conv_buf, size_t number_of_wchar, const char*
|
|||
#define stat_desc windows_stat_desc
|
||||
#undef sleep
|
||||
#define sleep windows_sleep
|
||||
#undef usleep
|
||||
#define usleep windows_usleep
|
||||
/* 4==DIR, 5,6,7=free, 8==REG */
|
||||
#define S_IFLNK 0x5000 /* Symbolic link to file */
|
||||
#define S_ISLNK(m) (((m) & _S_IFMT) == S_IFLNK)
|
||||
|
|
@ -434,16 +432,12 @@ const char* windows_stat_desc(struct stat* st);
|
|||
*/
|
||||
unsigned windows_sleep(unsigned seconds);
|
||||
|
||||
/**
|
||||
* Like usleep().
|
||||
*/
|
||||
void windows_usleep(uint64_t useconds);
|
||||
|
||||
/**
|
||||
* Like readlink().
|
||||
*/
|
||||
int windows_readlink(const char* file, char* buffer, size_t size);
|
||||
|
||||
|
||||
/**
|
||||
* Like symlink().
|
||||
* Return ENOSYS if symlinks are not supported.
|
||||
|
|
|
|||
11
os/os.h
11
os/os.h
|
|
@ -307,6 +307,16 @@ uint64_t os_tick_ms(void);
|
|||
*/
|
||||
uint64_t os_tick_sec(void);
|
||||
|
||||
/**
|
||||
* Sleep for the specified number of microseconds.
|
||||
*
|
||||
* Loops in bounded intervals and returns on the first error or signal interruption.
|
||||
* \param usec Number of microseconds to sleep.
|
||||
* \return 0 on success, -1 on error.
|
||||
*/
|
||||
int os_usleep(uint64_t usec);
|
||||
|
||||
|
||||
/**
|
||||
* Abort the process with a stacktrace.
|
||||
*/
|
||||
|
|
@ -343,3 +353,4 @@ int os_randomize(void* ptr, size_t size);
|
|||
int os_get_optimal_cpu(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
28
os/unix.c
28
os/unix.c
|
|
@ -1694,6 +1694,34 @@ uint64_t os_tick_sec(void)
|
|||
return ts.tv_sec;
|
||||
}
|
||||
|
||||
int os_usleep(uint64_t usec)
|
||||
{
|
||||
while (usec > 0) {
|
||||
unsigned chunk = 999999;
|
||||
if (usec < chunk)
|
||||
chunk = (unsigned)usec;
|
||||
|
||||
if (os_signal_interrupt()) {
|
||||
errno = EINTR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sleep in intervals of at most 999999 microseconds because POSIX usleep()
|
||||
* only accepts values less than 1,000,000 microseconds (< 1 second)
|
||||
* and may fail with EINVAL for larger values.
|
||||
*/
|
||||
if (usleep(chunk) != 0)
|
||||
return -1;
|
||||
|
||||
usec -= chunk;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int os_randomize(void* ptr, size_t size)
|
||||
{
|
||||
int f;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue