Compare commits
	
		
			4 Commits
		
	
	
		
			ca8e7b40bc
			...
			9213dd13bc
		
	
	| Author | SHA1 | Date | 
|---|---|---|
|  | 9213dd13bc | |
|  | 4273f43be1 | |
|  | 139bb5c2a5 | |
|  | 95e861bcdd | 
|  | @ -1,6 +1,7 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <BAN/Assert.h> | #include <BAN/Assert.h> | ||||||
|  | #include <BAN/PlacementNew.h> | ||||||
| 
 | 
 | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <stddef.h> | #include <stddef.h> | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ | ||||||
| 
 | 
 | ||||||
| #include <BAN/Errors.h> | #include <BAN/Errors.h> | ||||||
| #include <BAN/Move.h> | #include <BAN/Move.h> | ||||||
| #include <BAN/New.h> | #include <BAN/PlacementNew.h> | ||||||
| 
 | 
 | ||||||
| namespace BAN | namespace BAN | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ | ||||||
| #include <BAN/Errors.h> | #include <BAN/Errors.h> | ||||||
| #include <BAN/Move.h> | #include <BAN/Move.h> | ||||||
| #include <BAN/New.h> | #include <BAN/New.h> | ||||||
|  | #include <BAN/PlacementNew.h> | ||||||
| 
 | 
 | ||||||
| namespace BAN | namespace BAN | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -16,6 +16,3 @@ namespace BAN | ||||||
| 		static constexpr void(&deallocator)(void*) = free; | 		static constexpr void(&deallocator)(void*) = free; | ||||||
| 	#endif | 	#endif | ||||||
| } | } | ||||||
| 
 |  | ||||||
| inline void* operator new(size_t, void* addr)	{ return addr; } |  | ||||||
| inline void* operator new[](size_t, void* addr)	{ return addr; } |  | ||||||
|  |  | ||||||
|  | @ -2,6 +2,7 @@ | ||||||
| 
 | 
 | ||||||
| #include <BAN/Assert.h> | #include <BAN/Assert.h> | ||||||
| #include <BAN/Move.h> | #include <BAN/Move.h> | ||||||
|  | #include <BAN/PlacementNew.h> | ||||||
| 
 | 
 | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | inline void* operator new(size_t, void* addr)	{ return addr; } | ||||||
|  | inline void* operator new[](size_t, void* addr)	{ return addr; } | ||||||
|  | @ -5,6 +5,7 @@ | ||||||
| #include <BAN/Math.h> | #include <BAN/Math.h> | ||||||
| #include <BAN/Move.h> | #include <BAN/Move.h> | ||||||
| #include <BAN/New.h> | #include <BAN/New.h> | ||||||
|  | #include <BAN/PlacementNew.h> | ||||||
| 
 | 
 | ||||||
| namespace BAN | namespace BAN | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ | ||||||
| #include <BAN/Assert.h> | #include <BAN/Assert.h> | ||||||
| #include <BAN/Math.h> | #include <BAN/Math.h> | ||||||
| #include <BAN/Move.h> | #include <BAN/Move.h> | ||||||
| #include <BAN/New.h> | #include <BAN/PlacementNew.h> | ||||||
| 
 | 
 | ||||||
| #include <string.h> | #include <string.h> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ | ||||||
| #include <BAN/Math.h> | #include <BAN/Math.h> | ||||||
| #include <BAN/Move.h> | #include <BAN/Move.h> | ||||||
| #include <BAN/New.h> | #include <BAN/New.h> | ||||||
|  | #include <BAN/PlacementNew.h> | ||||||
| #include <BAN/Span.h> | #include <BAN/Span.h> | ||||||
| 
 | 
 | ||||||
| namespace BAN | namespace BAN | ||||||
|  |  | ||||||
|  | @ -19,11 +19,11 @@ SECTIONS | ||||||
| 		g_userspace_start = .; | 		g_userspace_start = .; | ||||||
| 		*(.userspace) | 		*(.userspace) | ||||||
| 		g_userspace_end = .; | 		g_userspace_end = .; | ||||||
|  | 		g_kernel_execute_end = .; | ||||||
| 	} | 	} | ||||||
| 	.rodata ALIGN(4K) : AT(ADDR(.rodata) - KERNEL_OFFSET) | 	.rodata ALIGN(4K) : AT(ADDR(.rodata) - KERNEL_OFFSET) | ||||||
| 	{ | 	{ | ||||||
| 		*(.rodata.*) | 		*(.rodata.*) | ||||||
| 		g_kernel_execute_end = .; |  | ||||||
| 	} | 	} | ||||||
| 	.data ALIGN(4K) : AT(ADDR(.data) - KERNEL_OFFSET) | 	.data ALIGN(4K) : AT(ADDR(.data) - KERNEL_OFFSET) | ||||||
| 	{ | 	{ | ||||||
|  |  | ||||||
|  | @ -35,9 +35,8 @@ namespace Kernel | ||||||
| 		bool is_locked() const; | 		bool is_locked() const; | ||||||
| 
 | 
 | ||||||
| 	private: | 	private: | ||||||
| 		BAN::Atomic<pid_t> m_locker = -1; | 		BAN::Atomic<pid_t>		m_locker		= -1; | ||||||
| 		BAN::Atomic<uint32_t> m_lock_depth = 0; | 		BAN::Atomic<uint32_t>	m_lock_depth	= 0; | ||||||
| 		SpinLock m_lock; |  | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	class RecursivePrioritySpinLock | 	class RecursivePrioritySpinLock | ||||||
|  | @ -54,10 +53,9 @@ namespace Kernel | ||||||
| 		uint32_t lock_depth() const { return m_lock_depth; } | 		uint32_t lock_depth() const { return m_lock_depth; } | ||||||
| 
 | 
 | ||||||
| 	private: | 	private: | ||||||
| 		pid_t m_locker = -1; | 		BAN::Atomic<pid_t>		m_locker		= -1; | ||||||
| 		uint32_t m_queue_length = 0; | 		BAN::Atomic<uint32_t>	m_lock_depth	= 0; | ||||||
| 		uint32_t m_lock_depth = 0; | 		BAN::Atomic<uint32_t>	m_queue_length	= 0; | ||||||
| 		SpinLock m_lock; |  | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -25,40 +25,21 @@ namespace Kernel | ||||||
| 	void RecursiveSpinLock::lock() | 	void RecursiveSpinLock::lock() | ||||||
| 	{ | 	{ | ||||||
| 		pid_t tid = Scheduler::current_tid(); | 		pid_t tid = Scheduler::current_tid(); | ||||||
| 
 | 		if (m_locker != tid) | ||||||
| 		while (true) |  | ||||||
| 		{ | 		{ | ||||||
| 			m_lock.lock(); | 			while (!m_locker.compare_exchange(-1, tid)) | ||||||
| 			if (m_locker == tid) | 				Scheduler::get().reschedule(); | ||||||
| 			{ | 			ASSERT(m_lock_depth == 0); | ||||||
| 				m_lock_depth++; |  | ||||||
| 				break; |  | ||||||
| 			} |  | ||||||
| 			if (m_locker == -1) |  | ||||||
| 			{ |  | ||||||
| 				m_locker = tid; |  | ||||||
| 				m_lock_depth = 1; |  | ||||||
| 				break; |  | ||||||
| 			} |  | ||||||
| 			m_lock.unlock(); |  | ||||||
| 		} | 		} | ||||||
| 
 | 		m_lock_depth++; | ||||||
| 		m_lock.unlock(); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void RecursiveSpinLock::unlock() | 	void RecursiveSpinLock::unlock() | ||||||
| 	{ | 	{ | ||||||
| 		m_lock.lock(); |  | ||||||
| 
 |  | ||||||
| 		ASSERT(m_lock_depth > 0); | 		ASSERT(m_lock_depth > 0); | ||||||
| 		ASSERT(m_locker == Scheduler::current_tid()); | 		ASSERT(m_locker == Scheduler::current_tid()); | ||||||
| 
 | 		if (--m_lock_depth == 0) | ||||||
| 		m_lock_depth--; |  | ||||||
| 
 |  | ||||||
| 		if (m_lock_depth == 0) |  | ||||||
| 			m_locker = -1; | 			m_locker = -1; | ||||||
| 
 |  | ||||||
| 		m_lock.unlock(); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	bool RecursiveSpinLock::is_locked() const | 	bool RecursiveSpinLock::is_locked() const | ||||||
|  | @ -71,38 +52,20 @@ namespace Kernel | ||||||
| 		pid_t tid = Scheduler::current_tid(); | 		pid_t tid = Scheduler::current_tid(); | ||||||
| 
 | 
 | ||||||
| 		bool has_priority = !Thread::current().is_userspace(); | 		bool has_priority = !Thread::current().is_userspace(); | ||||||
| 
 |  | ||||||
| 		if (has_priority) | 		if (has_priority) | ||||||
| 		{ |  | ||||||
| 			m_lock.lock(); |  | ||||||
| 			m_queue_length++; | 			m_queue_length++; | ||||||
| 			m_lock.unlock(); |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		while (true) | 		if (m_locker != tid) | ||||||
| 		{ | 		{ | ||||||
| 			m_lock.lock(); | 			while (!((has_priority || m_queue_length == 0) && m_locker.compare_exchange(-1, tid))) | ||||||
| 			if (m_locker == tid) | 				Scheduler::get().reschedule(); | ||||||
| 			{ | 			ASSERT(m_lock_depth == 0); | ||||||
| 				m_lock_depth++; |  | ||||||
| 				break; |  | ||||||
| 			} |  | ||||||
| 			if (m_locker == -1 && (has_priority || m_queue_length == 0)) |  | ||||||
| 			{ |  | ||||||
| 				m_locker = tid; |  | ||||||
| 				m_lock_depth = 1; |  | ||||||
| 				break; |  | ||||||
| 			} |  | ||||||
| 			m_lock.unlock(); |  | ||||||
| 		} | 		} | ||||||
| 
 | 		m_lock_depth++; | ||||||
| 		m_lock.unlock(); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void RecursivePrioritySpinLock::unlock() | 	void RecursivePrioritySpinLock::unlock() | ||||||
| 	{ | 	{ | ||||||
| 		m_lock.lock(); |  | ||||||
| 
 |  | ||||||
| 		ASSERT(m_lock_depth > 0); | 		ASSERT(m_lock_depth > 0); | ||||||
| 		ASSERT(m_locker == Scheduler::current_tid()); | 		ASSERT(m_locker == Scheduler::current_tid()); | ||||||
| 
 | 
 | ||||||
|  | @ -110,12 +73,8 @@ namespace Kernel | ||||||
| 		if (has_priority) | 		if (has_priority) | ||||||
| 			m_queue_length--; | 			m_queue_length--; | ||||||
| 
 | 
 | ||||||
| 		m_lock_depth--; | 		if (--m_lock_depth == 0) | ||||||
| 
 |  | ||||||
| 		if (m_lock_depth == 0) |  | ||||||
| 			m_locker = -1; | 			m_locker = -1; | ||||||
| 
 |  | ||||||
| 		m_lock.unlock(); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	bool RecursivePrioritySpinLock::is_locked() const | 	bool RecursivePrioritySpinLock::is_locked() const | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| #include <ctype.h> | #include <ctype.h> | ||||||
| #include <fcntl.h> | #include <fcntl.h> | ||||||
|  | #include <inttypes.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  | @ -7,35 +8,91 @@ | ||||||
| 
 | 
 | ||||||
| #define CURRENT_NS() ({ timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); ts.tv_sec * 1'000'000'000 + ts.tv_nsec; }) | #define CURRENT_NS() ({ timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); ts.tv_sec * 1'000'000'000 + ts.tv_nsec; }) | ||||||
| 
 | 
 | ||||||
| int parse_int(const char* val) | uint64_t parse_sized_u64(const char* val) | ||||||
| { | { | ||||||
| 	int result = 0; | 	uint64_t result = 0; | ||||||
| 	for (const char* ptr = val; *ptr; ptr++) | 
 | ||||||
| 	{ | 	const char* ptr = val; | ||||||
| 		if (!isdigit(*ptr)) | 	for (; *ptr && isdigit(*ptr); ptr++) | ||||||
| 		{ |  | ||||||
| 			fprintf(stderr, "invalid number: %s\n", val); |  | ||||||
| 			exit(1); |  | ||||||
| 		} |  | ||||||
| 		result = (result * 10) + (*ptr - '0'); | 		result = (result * 10) + (*ptr - '0'); | ||||||
|  | 
 | ||||||
|  | 	switch (*ptr) | ||||||
|  | 	{ | ||||||
|  | 		case 'E': result *= 1024; // fall through
 | ||||||
|  | 		case 'P': result *= 1024; // fall through
 | ||||||
|  | 		case 'T': result *= 1024; // fall through
 | ||||||
|  | 		case 'G': result *= 1024; // fall through
 | ||||||
|  | 		case 'M': result *= 1024; // fall through
 | ||||||
|  | 		case 'K': case 'k': result *= 1024; ptr++; break; | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	if (*ptr != '\0') | ||||||
|  | 	{ | ||||||
|  | 		fprintf(stderr, "invalid number: %s\n", val); | ||||||
|  | 		exit(1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void print_time(uint64_t start_ns, uint64_t end_ns, size_t transfered) | void print_value_with_unit(uint64_t value_x10, unsigned base, const char* units[]) | ||||||
|  | { | ||||||
|  | 	unsigned index = 0; | ||||||
|  | 	while (value_x10 / 10 >= base) | ||||||
|  | 	{ | ||||||
|  | 		index++; | ||||||
|  | 		value_x10 /= base; | ||||||
|  | 	} | ||||||
|  | 	if (value_x10 < 100) | ||||||
|  | 		printf("%u.%u %s", (unsigned)value_x10 / 10, (unsigned)value_x10 % 10, units[index]); | ||||||
|  | 	else | ||||||
|  | 		printf("%u %s", (unsigned)value_x10 / 10, units[index]); | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void print_time(uint64_t start_ns, uint64_t end_ns, uint64_t transfered, bool last = false) | ||||||
| { | { | ||||||
| 	static bool first = true; | 	static bool first = true; | ||||||
| 	uint64_t duration_ns = end_ns - start_ns; | 	if (!first) | ||||||
| 	printf("%s%zu bytes copied, %d.%09d s\e[K\n", (first ? "" : "\e[F"), transfered, (int)(duration_ns / 1'000'000'000), (int)(duration_ns % 1'000'000'000)); | 		printf("\e[F"); | ||||||
| 	first = false; | 	first = false; | ||||||
|  | 
 | ||||||
|  | 	printf("%" PRIu64 " bytes", transfered); | ||||||
|  | 	if (transfered >= 1000) | ||||||
|  | 	{ | ||||||
|  | 		printf(" ("); | ||||||
|  | 		{ | ||||||
|  | 			const char* units[] { "", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", "RB", "QB" }; | ||||||
|  | 			print_value_with_unit(transfered * 10, 1000, units); | ||||||
|  | 		} | ||||||
|  | 		if (transfered >= 1024) | ||||||
|  | 		{ | ||||||
|  | 			printf(", "); | ||||||
|  | 			const char* units[] { "", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB", "RiB", "QiB" }; | ||||||
|  | 			print_value_with_unit(transfered * 10, 1024, units); | ||||||
|  | 		} | ||||||
|  | 		printf(")"); | ||||||
|  | 	} | ||||||
|  | 	printf(" copied"); | ||||||
|  | 
 | ||||||
|  | 	double duration_s = (end_ns - start_ns) / 1e9; | ||||||
|  | 	if (last) | ||||||
|  | 		printf(", %f s, ", duration_s); | ||||||
|  | 	else | ||||||
|  | 		printf(", %u s, ", (unsigned)duration_s); | ||||||
|  | 
 | ||||||
|  | 	const char* units[] { "B/s", "kB/s", "MB/s", "GB/s", "TB/s", "PB/s", "EB/s", "ZB/s", "YB/s", "RB/s", "QB/s" }; | ||||||
|  | 	print_value_with_unit(10 * transfered / duration_s, 1000, units); | ||||||
|  | 
 | ||||||
|  | 	printf("\e[K\n"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int main(int argc, char** argv) | int main(int argc, char** argv) | ||||||
| { | { | ||||||
| 	const char* input = nullptr; | 	const char* input = nullptr; | ||||||
| 	const char* output = nullptr; | 	const char* output = nullptr; | ||||||
| 	int bs = 512; | 	uint64_t bs = 512; | ||||||
| 	int count = -1; | 	uint64_t count = ~(uint64_t)0; | ||||||
| 	bool print_progress = false; | 	bool print_progress = false; | ||||||
| 
 | 
 | ||||||
| 	for (int i = 1; i < argc; i++) | 	for (int i = 1; i < argc; i++) | ||||||
|  | @ -45,9 +102,9 @@ int main(int argc, char** argv) | ||||||
| 		else if (strncmp(argv[i], "of=", 3) == 0) | 		else if (strncmp(argv[i], "of=", 3) == 0) | ||||||
| 			output = argv[i] + 3; | 			output = argv[i] + 3; | ||||||
| 		else if (strncmp(argv[i], "bs=", 3) == 0) | 		else if (strncmp(argv[i], "bs=", 3) == 0) | ||||||
| 			bs = parse_int(argv[i] + 3); | 			bs = parse_sized_u64(argv[i] + 3); | ||||||
| 		else if (strncmp(argv[i], "count=", 6) == 0) | 		else if (strncmp(argv[i], "count=", 6) == 0) | ||||||
| 			count = parse_int(argv[i] + 6); | 			count = parse_sized_u64(argv[i] + 6); | ||||||
| 		else if (strcmp(argv[i], "status=progress") == 0) | 		else if (strcmp(argv[i], "status=progress") == 0) | ||||||
| 			print_progress = true; | 			print_progress = true; | ||||||
| 		else | 		else | ||||||
|  | @ -86,12 +143,11 @@ int main(int argc, char** argv) | ||||||
| 		return 1; | 		return 1; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	size_t total_transfered = 0; | 	uint64_t total_transfered = 0; | ||||||
| 
 |  | ||||||
| 	uint64_t start_ns = CURRENT_NS(); | 	uint64_t start_ns = CURRENT_NS(); | ||||||
| 	uint64_t last_print_ns = 0; | 	uint64_t last_print_s = 0; | ||||||
| 
 | 
 | ||||||
| 	for (int i = 0; i != count; i++) | 	for (uint64_t i = 0; i != count; i++) | ||||||
| 	{ | 	{ | ||||||
| 		ssize_t nread = read(ifd, buffer, bs); | 		ssize_t nread = read(ifd, buffer, bs); | ||||||
| 		if (nread == -1) | 		if (nread == -1) | ||||||
|  | @ -109,21 +165,21 @@ int main(int argc, char** argv) | ||||||
| 
 | 
 | ||||||
| 		total_transfered += nwrite; | 		total_transfered += nwrite; | ||||||
| 
 | 
 | ||||||
| 		if (nread < bs || nwrite < bs) | 		if ((size_t)nread < bs || (size_t)nwrite < bs) | ||||||
| 			break; | 			break; | ||||||
| 
 | 
 | ||||||
| 		if (print_progress) | 		if (print_progress) | ||||||
| 		{ | 		{ | ||||||
| 			uint64_t current_ns = CURRENT_NS(); | 			uint64_t current_ns = CURRENT_NS(); | ||||||
| 			if (current_ns >= last_print_ns + 1'000'000'000) | 			if ((current_ns - start_ns) / 1'000'000'000 > last_print_s) | ||||||
| 			{ | 			{ | ||||||
| 				print_time(start_ns, current_ns, total_transfered); | 				print_time(start_ns, current_ns, total_transfered); | ||||||
| 				last_print_ns = current_ns; | 				last_print_s = (current_ns - start_ns) / 1'000'000'000; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	print_time(start_ns, CURRENT_NS(), total_transfered); | 	print_time(start_ns, CURRENT_NS(), total_transfered, true); | ||||||
| 
 | 
 | ||||||
| 	close(ifd); | 	close(ifd); | ||||||
| 	close(ofd); | 	close(ofd); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue