about summary refs log tree commit diff
path: root/src/base
diff options
context:
space:
mode:
Diffstat (limited to 'src/base')
-rw-r--r--src/base/detect.h8
-rw-r--r--src/base/system.c80
-rw-r--r--src/base/system.h53
-rw-r--r--src/base/tl/threading.h106
-rw-r--r--src/base/vmath.h15
5 files changed, 221 insertions, 41 deletions
diff --git a/src/base/detect.h b/src/base/detect.h
index f9ca5779..0e2ef86a 100644
--- a/src/base/detect.h
+++ b/src/base/detect.h
@@ -63,7 +63,7 @@
 #if defined(__sun)
 	#define CONF_FAMILY_UNIX 1
 	#define CONF_FAMILY_STRING "unix"
-	#define CONF_PLATFROM_SOLARIS 1
+	#define CONF_PLATFORM_SOLARIS 1
 	#define CONF_PLATFORM_STRING "solaris"
 #endif
 
@@ -77,7 +77,7 @@
 
 
 /* use gcc endianness definitions when available */
-#if defined(__GNUC__) && !defined(__APPLE__)
+#if defined(__GNUC__) && !defined(__APPLE__) && !defined(__MINGW32__) && !defined(__sun)
 	#if defined(__FreeBSD__) || defined(__OpenBSD__)
 		#include <sys/endian.h>
 	#else
@@ -101,7 +101,7 @@
 	#endif
 #endif
 
-#if defined(__ia64__)
+#if defined(__ia64__) || defined(_M_IA64)
 	#define CONF_ARCH_IA64 1
 	#define CONF_ARCH_STRING "ia64"
 	#if !defined(CONF_ARCH_ENDIAN_LITTLE) && !defined(CONF_ARCH_ENDIAN_BIG)
@@ -109,7 +109,7 @@
 	#endif
 #endif
 
-#if defined(__amd64__) || defined(__x86_64__)
+#if defined(__amd64__) || defined(__x86_64__) || defined(_M_X64)
 	#define CONF_ARCH_AMD64 1
 	#define CONF_ARCH_STRING "amd64"
 	#if !defined(CONF_ARCH_ENDIAN_LITTLE) && !defined(CONF_ARCH_ENDIAN_BIG)
diff --git a/src/base/system.c b/src/base/system.c
index 466e3ca6..ed0f41ec 100644
--- a/src/base/system.c
+++ b/src/base/system.c
@@ -7,9 +7,7 @@
 #include <ctype.h>
 #include <time.h>
 
-/*#include "detect.h"*/
 #include "system.h"
-/*#include "e_console.h"*/
 
 #if defined(CONF_FAMILY_UNIX)
 	#include <sys/time.h>
@@ -46,6 +44,10 @@
 	#error NOT IMPLEMENTED
 #endif
 
+#if defined(CONF_PLATFORM_SOLARIS)
+	#include <sys/filio.h>
+#endif
+
 #if defined(__cplusplus)
 extern "C" {
 #endif
@@ -123,7 +125,7 @@ static IOHANDLE logfile = 0;
 static void logger_file(const char *line)
 {
 	io_write(logfile, line, strlen(line));
-	io_write(logfile, "\n", 1);
+	io_write_newline(logfile);
 	io_flush(logfile);
 }
 
@@ -140,8 +142,6 @@ void dbg_logger_file(const char *filename)
 }
 /* */
 
-int memory_alloced = 0;
-
 typedef struct MEMHEADER
 {
 	const char *filename;
@@ -163,8 +163,10 @@ void *mem_alloc_debug(const char *filename, int line, unsigned size, unsigned al
 {
 	/* TODO: fix alignment */
 	/* TODO: add debugging */
+	MEMTAIL *tail;
 	MEMHEADER *header = (struct MEMHEADER *)malloc(size+sizeof(MEMHEADER)+sizeof(MEMTAIL));
-	MEMTAIL *tail = (struct MEMTAIL *)(((char*)(header+1))+size);
+	dbg_assert(header != 0, "mem_alloc failure");
+	tail = (struct MEMTAIL *)(((char*)(header+1))+size);
 	header->size = size;
 	header->filename = filename;
 	header->line = line;
@@ -220,8 +222,9 @@ void mem_debug_dump(IOHANDLE file)
 	{
 		while(header)
 		{
-			str_format(buf, sizeof(buf), "%s(%d): %d\n", header->filename, header->line, header->size);
+			str_format(buf, sizeof(buf), "%s(%d): %d", header->filename, header->line, header->size);
 			io_write(file, buf, strlen(buf));
+			io_write_newline(file);
 			header = header->next;
 		}
 
@@ -276,8 +279,13 @@ IOHANDLE io_open(const char *filename, int flags)
 		if(!filename || !length || filename[length-1] == '\\')
 			return 0x0;
 		handle = FindFirstFile(filename, &finddata);
-		if(handle == INVALID_HANDLE_VALUE || str_comp(filename+length-str_length(finddata.cFileName), finddata.cFileName))
+		if(handle == INVALID_HANDLE_VALUE)
+			return 0x0;
+		else if(str_comp(filename+length-str_length(finddata.cFileName), finddata.cFileName) != 0)
+		{
+			FindClose(handle);
 			return 0x0;
+		}
 		FindClose(handle);
 	#endif
 		return (IOHANDLE)fopen(filename, "rb");
@@ -339,6 +347,15 @@ unsigned io_write(IOHANDLE io, const void *buffer, unsigned size)
 	return fwrite(buffer, 1, size, (FILE*)io);
 }
 
+unsigned io_write_newline(IOHANDLE io)
+{
+#if defined(CONF_FAMILY_WINDOWS)
+	return fwrite("\r\n", 1, 2, (FILE*)io);
+#else
+	return fwrite("\n", 1, 1, (FILE*)io);
+#endif
+}
+
 int io_close(IOHANDLE io)
 {
 	fclose((FILE*)io);
@@ -488,6 +505,21 @@ void lock_release(LOCK lock)
 #endif
 }
 
+#if defined(CONF_FAMILY_UNIX)
+void semaphore_init(SEMAPHORE *sem) { sem_init(sem, 0, 0); }
+void semaphore_wait(SEMAPHORE *sem) { sem_wait(sem); }
+void semaphore_signal(SEMAPHORE *sem) { sem_post(sem); }
+void semaphore_destroy(SEMAPHORE *sem) { sem_destroy(sem); }
+#elif defined(CONF_FAMILY_WINDOWS)
+void semaphore_init(SEMAPHORE *sem) { *sem = CreateSemaphore(0, 0, 10000, 0); }
+void semaphore_wait(SEMAPHORE *sem) { WaitForSingleObject((HANDLE)*sem, 0L); }
+void semaphore_signal(SEMAPHORE *sem) { ReleaseSemaphore((HANDLE)*sem, 1, NULL); }
+void semaphore_destroy(SEMAPHORE *sem) { CloseHandle((HANDLE)*sem); }
+#else
+	#error not implemented on this platform
+#endif
+
+
 /* -----  time ----- */
 int64 time_get()
 {
@@ -578,18 +610,18 @@ int net_addr_comp(const NETADDR *a, const NETADDR *b)
 	return mem_comp(a, b, sizeof(NETADDR));
 }
 
-void net_addr_str(const NETADDR *addr, char *string, int max_length)
+void net_addr_str(const NETADDR *addr, char *string, int max_length, int add_port)
 {
 	if(addr->type == NETTYPE_IPV4)
 	{
-		if(addr->port != 0)
+		if(add_port != 0)
 			str_format(string, max_length, "%d.%d.%d.%d:%d", addr->ip[0], addr->ip[1], addr->ip[2], addr->ip[3], addr->port);
 		else
 			str_format(string, max_length, "%d.%d.%d.%d", addr->ip[0], addr->ip[1], addr->ip[2], addr->ip[3]);
 	}
 	else if(addr->type == NETTYPE_IPV6)
 	{
-		if(addr->port != 0)
+		if(add_port != 0)
 			str_format(string, max_length, "[%x:%x:%x:%x:%x:%x:%x:%x]:%d",
 				(addr->ip[0]<<8)|addr->ip[1], (addr->ip[2]<<8)|addr->ip[3], (addr->ip[4]<<8)|addr->ip[5], (addr->ip[6]<<8)|addr->ip[7],
 				(addr->ip[8]<<8)|addr->ip[9], (addr->ip[10]<<8)|addr->ip[11], (addr->ip[12]<<8)|addr->ip[13], (addr->ip[14]<<8)|addr->ip[15],
@@ -824,7 +856,15 @@ static int priv_net_create_socket(int domain, int type, struct sockaddr *addr, i
 	sock = socket(domain, type, 0);
 	if(sock < 0)
 	{
+#if defined(CONF_FAMILY_WINDOWS)
+		char buf[128];
+		int error = WSAGetLastError();
+		if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, 0, error, 0, buf, sizeof(buf), 0) == 0)
+			buf[0] = 0;
+		dbg_msg("net", "failed to create socket with domain %d and type %d (%d '%s')", domain, type, error, buf);
+#else
 		dbg_msg("net", "failed to create socket with domain %d and type %d (%d '%s')", domain, type, errno, strerror(errno));
+#endif
 		return -1;
 	}
 
@@ -841,7 +881,15 @@ static int priv_net_create_socket(int domain, int type, struct sockaddr *addr, i
 	e = bind(sock, addr, sockaddrlen);
 	if(e != 0)
 	{
+#if defined(CONF_FAMILY_WINDOWS)
+		char buf[128];
+		int error = WSAGetLastError();
+		if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, 0, error, 0, buf, sizeof(buf), 0) == 0)
+			buf[0] = 0;
+		dbg_msg("net", "failed to bind socket with domain %d and type %d (%d '%s')", domain, type, error, buf);
+#else
 		dbg_msg("net", "failed to bind socket with domain %d and type %d (%d '%s')", domain, type, errno, strerror(errno));
+#endif
 		priv_net_close_socket(sock);
 		return -1;
 	}
@@ -1119,7 +1167,7 @@ int net_tcp_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR *a)
 		sockaddr_len = sizeof(addr);
 
 		s = accept(sock.ipv4sock, (struct sockaddr *)&addr, &sockaddr_len);
-		
+
 		if (s != -1)
 		{
 			sockaddr_to_netaddr((const struct sockaddr *)&addr, a);
@@ -1135,7 +1183,7 @@ int net_tcp_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR *a)
 		sockaddr_len = sizeof(addr);
 
 		s = accept(sock.ipv6sock, (struct sockaddr *)&addr, &sockaddr_len);
-		
+
 		if (s != -1)
 		{
 			sockaddr_to_netaddr((const struct sockaddr *)&addr, a);
@@ -1186,7 +1234,7 @@ int net_tcp_send(NETSOCKET sock, const void *data, int size)
 		bytes = send((int)sock.ipv4sock, (const char*)data, size, 0);
 	if(sock.ipv6sock >= 0)
 		bytes = send((int)sock.ipv6sock, (const char*)data, size, 0);
-		
+
 	return bytes;
 }
 
@@ -1198,7 +1246,7 @@ int net_tcp_recv(NETSOCKET sock, void *data, int maxsize)
 		bytes = recv((int)sock.ipv4sock, (char*)data, maxsize, 0);
 	if(sock.ipv6sock >= 0)
 		bytes = recv((int)sock.ipv6sock, (char*)data, maxsize, 0);
-		
+
 	return bytes;
 }
 
@@ -1477,7 +1525,7 @@ int net_socket_read_wait(NETSOCKET sock, int time)
 	return 0;
 }
 
-unsigned time_timestamp()
+int time_timestamp()
 {
 	return time(0);
 }
diff --git a/src/base/system.h b/src/base/system.h
index aaa5b43f..b3588dbf 100644
--- a/src/base/system.h
+++ b/src/base/system.h
@@ -240,6 +240,18 @@ unsigned io_skip(IOHANDLE io, int size);
 unsigned io_write(IOHANDLE io, const void *buffer, unsigned size);
 
 /*
+	Function: io_write_newline
+		Writes newline to file.
+
+	Parameters:
+		io - Handle to the file.
+
+	Returns:
+		Number of bytes written.
+*/
+unsigned io_write_newline(IOHANDLE io);
+
+/*
 	Function: io_seek
 		Seeks to a specified offset in the file.
 
@@ -388,6 +400,23 @@ int lock_try(LOCK lock);
 void lock_wait(LOCK lock);
 void lock_release(LOCK lock);
 
+
+/* Group: Semaphores */
+
+#if defined(CONF_FAMILY_UNIX)
+	#include <semaphore.h>
+	typedef sem_t SEMAPHORE;
+#elif defined(CONF_FAMILY_WINDOWS)
+	typedef void* SEMAPHORE;
+#else
+	#error missing sempahore implementation
+#endif
+
+void semaphore_init(SEMAPHORE *sem);
+void semaphore_wait(SEMAPHORE *sem);
+void semaphore_signal(SEMAPHORE *sem);
+void semaphore_destroy(SEMAPHORE *sem);
+
 /* Group: Timer */
 #ifdef __GNUC__
 /* if compiled with -pedantic-errors it will complain about long
@@ -425,7 +454,7 @@ int64 time_freq();
 	Returns:
 		The time as a UNIX timestamp
 */
-unsigned time_timestamp();
+int time_timestamp();
 
 /* Group: Network General */
 typedef struct
@@ -499,12 +528,13 @@ int net_addr_comp(const NETADDR *a, const NETADDR *b);
 		addr - Address to turn into a string.
 		string - Buffer to fill with the string.
 		max_length - Maximum size of the string.
+		add_port - add port to string or not
 
 	Remarks:
 		- The string will always be zero terminated
 
 */
-void net_addr_str(const NETADDR *addr, char *string, int max_length);
+void net_addr_str(const NETADDR *addr, char *string, int max_length, int add_port);
 
 /*
 	Function: net_addr_from_str
@@ -1130,25 +1160,6 @@ void mem_debug_dump(IOHANDLE file);
 
 void swap_endian(void *data, unsigned elem_size, unsigned num);
 
-/* Group: Debug levels */
-//by format
-enum {
-	DBG_FMT_RAW				= 1,	//raw output
-	DBG_FMT_TIME			= 2,	//show time
-	DBG_FMT_SYS				= 3,	//show sys
-	DBG_FMT_FULL			= 4		//show both
-};
-
-enum {
-	DBG_LEVEL_IMPORTANT			= 0,	//important always showed messages
-	DBG_LEVEL_ERROR				= 1,	//error messages
-	DBG_LEVEL_WARNING			= 2,	//warning messages
-	DBG_LEVEL_MSG				= 3,	//extra debug messages
-	DBG_LEVEL_INFO				= 4		//info messages
-};
-
-#define DBG_LEVEL_LOW DBG_LEVEL_IMPORTANT
-#define DBG_LEVEL_HIGH DBG_LEVEL_INFO
 
 typedef void (*DBG_LOGGER)(const char *line);
 void dbg_logger(DBG_LOGGER logger);
diff --git a/src/base/tl/threading.h b/src/base/tl/threading.h
new file mode 100644
index 00000000..dbf788cd
--- /dev/null
+++ b/src/base/tl/threading.h
@@ -0,0 +1,106 @@
+
+#pragma once
+
+#include "../system.h"
+
+/*
+	atomic_inc - should return the value after increment
+	atomic_dec - should return the value after decrement
+	atomic_compswap - should return the value before the eventual swap
+	
+*/
+
+#if defined(__GNUC__)
+
+	inline unsigned atomic_inc(volatile unsigned *pValue)
+	{
+		return __sync_fetch_and_add(pValue, 1);
+	}
+
+	inline unsigned atomic_dec(volatile unsigned *pValue)
+	{
+		return __sync_fetch_and_add(pValue, -1);
+	}
+
+	inline unsigned atomic_compswap(volatile unsigned *pValue, unsigned comperand, unsigned value)
+	{
+		return __sync_val_compare_and_swap(pValue, comperand, value);
+	}
+
+	inline void sync_barrier()
+	{
+		__sync_synchronize();
+	}
+
+#elif defined(_MSC_VER)
+	#include <intrin.h>
+
+	inline unsigned atomic_inc(volatile unsigned *pValue)
+	{
+		return _InterlockedIncrement((volatile long *)pValue);
+	}
+	
+	inline unsigned atomic_dec(volatile unsigned *pValue)
+	{
+		return _InterlockedDecrement((volatile long *)pValue);
+	}
+
+	inline unsigned atomic_compswap(volatile unsigned *pValue, unsigned comperand, unsigned value)
+	{
+		return _InterlockedCompareExchange((volatile long *)pValue, (long)value, (long)comperand);
+	}
+
+	inline void sync_barrier()
+	{
+		_ReadWriteBarrier();
+	}
+#else
+	#error missing atomic implementation for this compiler
+#endif
+
+class semaphore
+{
+	SEMAPHORE sem;
+public:
+	semaphore() { semaphore_init(&sem); }
+	~semaphore() { semaphore_destroy(&sem); }
+	void wait() { semaphore_wait(&sem); }
+	void signal() { semaphore_signal(&sem); }
+};
+
+class lock
+{
+	friend class scope_lock;
+
+	LOCK var;
+
+	void take() { lock_wait(var); }
+	void release() { lock_release(var); }
+
+public:
+	lock()
+	{
+		var = lock_create();
+	}
+
+	~lock()
+	{
+		lock_destroy(var);
+	}
+};
+
+class scope_lock
+{
+	lock *var;
+public:
+	scope_lock(lock *l)
+	{
+		var = l;
+		var->take();
+	}
+
+	~scope_lock()
+	{
+		var->release();
+	}
+};
diff --git a/src/base/vmath.h b/src/base/vmath.h
index 3461adf8..df10d904 100644
--- a/src/base/vmath.h
+++ b/src/base/vmath.h
@@ -25,12 +25,18 @@ public:
 	vector2_base operator -(const vector2_base &v) const { return vector2_base(x-v.x, y-v.y); }
 	vector2_base operator +(const vector2_base &v) const { return vector2_base(x+v.x, y+v.y); }
 	vector2_base operator *(const T v) const { return vector2_base(x*v, y*v); }
+	vector2_base operator *(const vector2_base &v) const { return vector2_base(x*v.x, y*v.y); }
+	vector2_base operator /(const T v) const { return vector3_base(x/v, y/v); }
+	vector2_base operator /(const vector2_base &v) const { return vector2_base(x/v.x, y/v.y); }
 
 	const vector2_base &operator =(const vector2_base &v) { x = v.x; y = v.y; return *this; }
 
 	const vector2_base &operator +=(const vector2_base &v) { x += v.x; y += v.y; return *this; }
 	const vector2_base &operator -=(const vector2_base &v) { x -= v.x; y -= v.y; return *this; }
 	const vector2_base &operator *=(const T v) { x *= v; y *= v; return *this;	}
+	const vector2_base &operator *=(const vector2_base &v) { x *= v.x; y *= v.y; return *this; }
+	const vector2_base &operator /=(const T v) { x /= v; y /= v; return *this;	}
+	const vector2_base &operator /=(const vector2_base &v) { x /= v.x; y /= v.y; return *this; }
 
 	bool operator ==(const vector2_base &v) const { return x == v.x && y == v.y; } //TODO: do this with an eps instead
 
@@ -107,10 +113,14 @@ public:
 	vector3_base operator *(const T v) const { return vector3_base(x*v, y*v, z*v); }
 	vector3_base operator *(const vector3_base &v) const { return vector3_base(x*v.x, y*v.y, z*v.z); }
 	vector3_base operator /(const T v) const { return vector3_base(x/v, y/v, z/v); }
+	vector3_base operator /(const vector3_base &v) const { return vector3_base(x/v.x, y/v.y, z/v.z); }
 
 	const vector3_base &operator +=(const vector3_base &v) { x += v.x; y += v.y; z += v.z; return *this; }
 	const vector3_base &operator -=(const vector3_base &v) { x -= v.x; y -= v.y; z -= v.z; return *this; }
 	const vector3_base &operator *=(const T v) { x *= v; y *= v; z *= v; return *this;	}
+	const vector3_base &operator *=(const vector3_base &v) { x *= v.x; y *= v.y; z *= v.z; return *this; }
+	const vector3_base &operator /=(const T v) { x /= v; y /= v; z /= v; return *this;	}
+	const vector3_base &operator /=(const vector3_base &v) { x /= v.x; y /= v.y; z /= v.z; return *this; }
 
 	bool operator ==(const vector3_base &v) const { return x == v.x && y == v.y && z == v.z; } //TODO: do this with an eps instead
 
@@ -180,12 +190,17 @@ public:
 	vector4_base operator -() const { return vector4_base(-x, -y, -z, -w); }
 	vector4_base operator *(const vector4_base &v) const { return vector4_base(x*v.x, y*v.y, z*v.z, w*v.w); }
 	vector4_base operator *(const T v) const { return vector4_base(x*v, y*v, z*v, w*v); }
+	vector4_base operator /(const vector4_base &v) const { return vector4_base(x/v.x, y/v.y, z/v.z, w/v.w); }
+	vector4_base operator /(const T v) const { return vector4_base(x/v, y/v, z/v, w/v); }
 
 	const vector4_base &operator =(const vector4_base &v) { x = v.x; y = v.y; z = v.z; w = v.w; return *this; }
 
 	const vector4_base &operator +=(const vector4_base &v) { x += v.x; y += v.y; z += v.z; w += v.w; return *this; }
 	const vector4_base &operator -=(const vector4_base &v) { x -= v.x; y -= v.y; z -= v.z; w -= v.w; return *this; }
 	const vector4_base &operator *=(const T v) { x *= v; y *= v; z *= v; w *= v; return *this;	}
+	const vector4_base &operator *=(const vector4_base &v) { x *= v.x; y *= v.y; z *= v.z; w *= v.w; return *this; }
+	const vector4_base &operator /=(const T v) { x /= v; y /= v; z /= v; w /= v; return *this;	}
+	const vector4_base &operator /=(const vector4_base &v) { x /= v.x; y /= v.y; z /= v.z; w /= v.w; return *this; }
 
 	bool operator ==(const vector4_base &v) const { return x == v.x && y == v.y && z == v.z && w == v.w; } //TODO: do this with an eps instead