diff --git a/aqvm/base/file/file.c b/aqvm/base/file/file.c index 9b3ac80..84c1ec0 100644 --- a/aqvm/base/file/file.c +++ b/aqvm/base/file/file.c @@ -18,11 +18,11 @@ int AqvmBaseFile_LockFile(struct AqvmBaseFile_File* stream) { return -1; } - int result = AqvmBaseThreadingMutex_LockMutex(&stream->mutex); + /*int result = AqvmBaseThreadingMutex_LockMutex(&stream->mutex); if (result != 0) { // TODO return -2; - } + }*/ return 0; } @@ -32,11 +32,11 @@ int AqvmBaseFile_UnlockFile(struct AqvmBaseFile_File* stream) { return -1; } - int result = AqvmBaseThreadingMutex_UnlockMutex(&stream->mutex); + /*int result = AqvmBaseThreadingMutex_UnlockMutex(&stream->mutex); if (result != 0) { // TODO return -2; - } + }*/ return 0; } @@ -60,10 +60,6 @@ int AqvmBaseFile_LockStream(struct AqvmBaseFile_File* stream) { // TODO return -4; } - if (AqvmBaseFile_LockFile(stream) != 0) { - // TODO - return -5; - } } return 0; @@ -89,10 +85,6 @@ int AqvmBaseFile_UnlockStream(struct AqvmBaseFile_File* stream) { // TODO return -4; } - if (AqvmBaseFile_UnlockFile(stream) != 0) { - // TODO - return -5; - } } return 0; @@ -131,10 +123,10 @@ int AqvmBaseFile_fclose(struct AqvmBaseFile_File* stream) { } int result = fclose(stream->file); - if (AqvmBaseThreadingMutex_CloseMutex(&stream->mutex)) { + /*if (AqvmBaseThreadingMutex_CloseMutex(&stream->mutex)) { // TODO return -2; - } + }*/ if (result != 0) { // TODO @@ -238,11 +230,11 @@ struct AqvmBaseFile_File* AqvmBaseFile_fopen(const char* filename, return NULL; } - if (AqvmBaseThreadingMutex_InitializeMutex(&stream->mutex) != 0) { + /*if (AqvmBaseThreadingMutex_InitializeMutex(&stream->mutex) != 0) { fclose(stream->file); free(stream); return NULL; - } + }*/ return stream; } @@ -507,12 +499,13 @@ struct AqvmBaseFile_File* AqvmBaseFile_tmpfile(void) { return NULL; } - AqvmBaseThreadingMutex_InitializeMutex(&stream->mutex); + /*AqvmBaseThreadingMutex_InitializeMutex(&stream->mutex);*/ return stream; } -char* AqvmBaseFile_tmpnam(char* str) { // TODO +char* AqvmBaseFile_tmpnam(char* str) { + // TODO char* result = tmpnam(str); if (result == NULL) { // TODO diff --git a/aqvm/base/file/file.h b/aqvm/base/file/file.h index a520d70..0adc73f 100644 --- a/aqvm/base/file/file.h +++ b/aqvm/base/file/file.h @@ -8,11 +8,13 @@ #include #include -#include "aqvm/base/threading/mutex/mutex.h" +#include "aqvm/base/file/identifier/identifier.h" +#include "aqvm/base/file/read_write_lock/read_write_lock.h" struct AqvmBaseFile_File { FILE* file; - AqvmBaseThreadingMutex_Mutex mutex; + AqvmBaseFileIdentifier_Identifier identifier; + struct AqvmBaseFileReadWriteLock_ReadWriteLock lock; }; int AqvmBaseFile_LockFile(struct AqvmBaseFile_File* stream); @@ -38,24 +40,23 @@ int AqvmBaseFile_fflush(struct AqvmBaseFile_File* stream); int AqvmBaseFile_fgetpos(struct AqvmBaseFile_File* stream, fpos_t* pos); struct AqvmBaseFile_File* AqvmBaseFile_fopen(const char* filename, - const char* mode); + const char* mode); size_t AqvmBaseFile_fread(void* ptr, size_t size, size_t nmemb, - struct AqvmBaseFile_File* stream); + struct AqvmBaseFile_File* stream); -struct AqvmBaseFile_File* AqvmBaseFile_freopen(const char* filename, - const char* mode, - struct AqvmBaseFile_File* stream); +struct AqvmBaseFile_File* AqvmBaseFile_freopen( + const char* filename, const char* mode, struct AqvmBaseFile_File* stream); int AqvmBaseFile_fseek(struct AqvmBaseFile_File* stream, long int offset, - int whence); + int whence); int AqvmBaseFile_fsetpos(struct AqvmBaseFile_File* stream, const fpos_t* pos); long int AqvmBaseFile_ftell(struct AqvmBaseFile_File* stream); size_t AqvmBaseFile_fwrite(const void* ptr, size_t size, size_t nmemb, - struct AqvmBaseFile_File* stream); + struct AqvmBaseFile_File* stream); int AqvmBaseFile_remove(const char* filename); @@ -65,8 +66,8 @@ void AqvmBaseFile_rewind(struct AqvmBaseFile_File* stream); void AqvmBaseFile_setbuf(struct AqvmBaseFile_File* stream, char* buffer); -int AqvmBaseFile_setvbuf(struct AqvmBaseFile_File* stream, char* buffer, int mode, - size_t size); +int AqvmBaseFile_setvbuf(struct AqvmBaseFile_File* stream, char* buffer, + int mode, size_t size); struct AqvmBaseFile_File* AqvmBaseFile_tmpfile(void); diff --git a/aqvm/base/file/read_write_lock/CMakeLists.txt b/aqvm/base/file/read_write_lock/CMakeLists.txt new file mode 100644 index 0000000..d234cd8 --- /dev/null +++ b/aqvm/base/file/read_write_lock/CMakeLists.txt @@ -0,0 +1,11 @@ +# Copyright 2024 AQ author, All Rights Reserved. +# This program is licensed under the AQ License. You can find the AQ license in +# the root directory. + +cmake_minimum_required(VERSION 3.10) + +include_directories(${PROJECT_SOURCE_DIR}) + +set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/read_write_lock.c) + +add_library(AqvmBaseFileReadWriteLock STATIC ${SOURCES}) \ No newline at end of file diff --git a/aqvm/base/file/read_write_lock/read_write_lock.c b/aqvm/base/file/read_write_lock/read_write_lock.c new file mode 100644 index 0000000..b08032a --- /dev/null +++ b/aqvm/base/file/read_write_lock/read_write_lock.c @@ -0,0 +1,85 @@ +// Copyright 2024 AQ author, All Rights Reserved. +// This program is licensed under the AQ License. You can find the AQ license in +// the root directory. + +#include "aqvm/base/file/read_write_lock/read_write_lock.h" + +int AqvmBaseFileReadWriteLock_InitializeReadWriteLock( + struct AqvmBaseFileReadWriteLock_ReadWriteLock* read_write_lock) { + if (read_write_lock == NULL) { + // TODO + return -1; + } + + if (AqvmBaseThreadingMutex_InitializeMutex(&read_write_lock->mutex) != 0) { + // TODO + return -2; + } + read_write_lock->read_count = 0; + return 0; +} + +int AqvmBaseFileReadWriteLock_CloseReadWriteLock( + struct AqvmBaseFileReadWriteLock_ReadWriteLock* read_write_lock) { + if (read_write_lock == NULL) { + // TODO + return -1; + } + + if (AqvmBaseThreadingMutex_CloseMutex(&read_write_lock->mutex) != 0) { + // TODO + return -2; + } + return 0; +} + +int AqvmBaseFileReadWriteLock_LockReadLock( + struct AqvmBaseFileReadWriteLock_ReadWriteLock* read_write_lock) { + if (read_write_lock == NULL) { + // TODO + return -1; + } + + if (AqvmBaseThreadingMutex_LockMutex(&read_write_lock->mutex) != 0) { + // TODO + return -2; + } + ++read_write_lock->read_count; + return 0; +} + +int AqvmBaseFileReadWriteLock_LockWriteLock( + struct AqvmBaseFileReadWriteLock_ReadWriteLock* read_write_lock) { + if (read_write_lock == NULL) { + // TODO + return -1; + } + + if (AqvmBaseThreadingMutex_LockMutex(&read_write_lock->mutex) != 0) { + // TODO + return -2; + } + return 0; +} + +int AqvmBaseFileReadWriteLock_UnlockLock( + struct AqvmBaseFileReadWriteLock_ReadWriteLock* read_write_lock) { + if (read_write_lock == NULL) { + // TODO + return -1; + } + + if (read_write_lock->read_count == 0 && + AqvmBaseThreadingMutex_UnlockMutex(&read_write_lock->mutex) != 0) { + // TODO + return -2; + } else { + --read_write_lock->read_count; + if (read_write_lock->read_count == 0 && + AqvmBaseThreadingMutex_UnlockMutex(&read_write_lock->mutex) != 0) { + // TODO + return -3; + } + } + return 0; +} \ No newline at end of file diff --git a/aqvm/base/file/read_write_lock/read_write_lock.h b/aqvm/base/file/read_write_lock/read_write_lock.h new file mode 100644 index 0000000..a00aed6 --- /dev/null +++ b/aqvm/base/file/read_write_lock/read_write_lock.h @@ -0,0 +1,30 @@ +// Copyright 2024 AQ author, All Rights Reserved. +// This program is licensed under the AQ License. You can find the AQ license in +// the root directory. + +#ifndef AQ_AQVM_BASE_FILE_READ_WRITE_LOCK_READ_WRITE_LOCK_H_ +#define AQ_AQVM_BASE_FILE_READ_WRITE_LOCK_READ_WRITE_LOCK_H_ + +#include "aqvm/base/threading/mutex/mutex.h" + +struct AqvmBaseFileReadWriteLock_ReadWriteLock { + AqvmBaseThreadingMutex_Mutex mutex; + int read_count; +}; + +int AqvmBaseFileReadWriteLock_InitializeReadWriteLock( + struct AqvmBaseFileReadWriteLock_ReadWriteLock* read_write_lock); + +int AqvmBaseFileReadWriteLock_CloseReadWriteLock( + struct AqvmBaseFileReadWriteLock_ReadWriteLock* read_write_lock); + +int AqvmBaseFileReadWriteLock_LockReadLock( + struct AqvmBaseFileReadWriteLock_ReadWriteLock* read_write_lock); + +int AqvmBaseFileReadWriteLock_LockWriteLock( + struct AqvmBaseFileReadWriteLock_ReadWriteLock* read_write_lock); + +int AqvmBaseFileReadWriteLock_UnlockLock( + struct AqvmBaseFileReadWriteLock_ReadWriteLock* read_write_lock); + +#endif \ No newline at end of file diff --git a/aqvm/base/hash/table/table.c b/aqvm/base/hash/table/table.c index 06e9a98..78c73f1 100644 --- a/aqvm/base/hash/table/table.c +++ b/aqvm/base/hash/table/table.c @@ -2,4 +2,50 @@ // This program is licensed under the AQ License. You can find the AQ license in // the root directory. -#include "aqvm/base/hash/table/table.h" \ No newline at end of file +#include "aqvm/base/hash/table/table.h" + +#include +#include + +#include "aqvm/base/linked_list/linked_list.h" + +int AqvmBaseHashTable_CloseHashTable( + struct AqvmBaseHashTable_HashTable* hash_table) { + if (hash_table == NULL) { + // TODO + return -1; + } + + for (size_t i = 0; i < hash_table->capacity; i++) { + AqvmBaseLinkedList_CloseLinkedList(&hash_table->data[i]); + } + free(hash_table->data); + hash_table->data = NULL; + hash_table->capacity = 0; + hash_table->size = 0; + return 0; +} + +int AqvmBaseHashTable_InitializeHashTable( + struct AqvmBaseHashTable_HashTable* hash_table, size_t capacity) { + if (hash_table == NULL || capacity == 0) { + // TODO + return -1; + } + + hash_table->capacity = capacity; + hash_table->size = 0; + hash_table->data = (struct AqvmBaseLinkedList_LinkedList*)malloc( + sizeof(struct AqvmBaseLinkedList_LinkedList) * capacity); + if (hash_table->data == NULL) { + // TODO + return -2; + } + for (size_t i = 0; i < capacity; i++) { + if (AqvmBaseLinkedList_InitializeLinkedList(&hash_table->data[i])) { + // TODO + return -3; + } + } + return 0; +} \ No newline at end of file diff --git a/aqvm/base/hash/table/table.h b/aqvm/base/hash/table/table.h index 049098f..b7cfac4 100644 --- a/aqvm/base/hash/table/table.h +++ b/aqvm/base/hash/table/table.h @@ -5,4 +5,20 @@ #ifndef AQ_AQVM_BASE_HASH_TABLE_TABLE_H_ #define AQ_AQVM_BASE_HASH_TABLE_TABLE_H_ +#include + +#include "aqvm/base/linked_list/linked_list.h" + +struct AqvmBaseHashTable_HashTable { + size_t capacity; + size_t size; + struct AqvmBaseLinkedList_LinkedList* data; +}; + +int AqvmBaseHashTable_CloseHashTable( + struct AqvmBaseHashTable_HashTable* hash_table); + +int AqvmBaseHashTable_InitializeHashTable( + struct AqvmBaseHashTable_HashTable* hash_table, size_t capacity); + #endif \ No newline at end of file diff --git a/aqvm/base/linked_list/linked_list.c b/aqvm/base/linked_list/linked_list.c index 82b213f..456827a 100644 --- a/aqvm/base/linked_list/linked_list.c +++ b/aqvm/base/linked_list/linked_list.c @@ -30,20 +30,6 @@ int AqvmBaseLinkedList_AddNode(struct AqvmBaseLinkedList_LinkedList* list, return 0; } -struct AqvmBaseLinkedList_LinkedList* AqvmBaseLinkedList_CreateLinkedList() { - struct AqvmBaseLinkedList_LinkedList* result = - (struct AqvmBaseLinkedList_LinkedList*)malloc( - sizeof(struct AqvmBaseLinkedList_LinkedList)); - if (result == NULL) { - // TODO - return NULL; - } - result->head = NULL; - result->tail = NULL; - result->capacity = 0; - return result; -} - int AqvmBaseLinkedList_CloseLinkedList( struct AqvmBaseLinkedList_LinkedList* list) { if (list == NULL) { @@ -57,7 +43,6 @@ int AqvmBaseLinkedList_CloseLinkedList( return -2; } } - free(list); return 0; } @@ -99,6 +84,18 @@ void* AqvmBaseLinkedList_GetData(struct AqvmBaseLinkedList_LinkedList* list, return get_node->data; } +int AqvmBaseLinkedList_InitializeLinkedList( + struct AqvmBaseLinkedList_LinkedList* linked_list) { + if (linked_list == NULL) { + // TODO + return -1; + } + linked_list->head = NULL; + linked_list->tail = NULL; + linked_list->capacity = 0; + return linked_list; +} + int AqvmBaseLinkedList_InsertNode(struct AqvmBaseLinkedList_LinkedList* list, size_t index, void* data) { if (list == NULL || index >= list->capacity) { diff --git a/aqvm/base/linked_list/linked_list.h b/aqvm/base/linked_list/linked_list.h index 8e1bd9b..f054c1b 100644 --- a/aqvm/base/linked_list/linked_list.h +++ b/aqvm/base/linked_list/linked_list.h @@ -22,8 +22,6 @@ struct AqvmBaseLinkedList_Node { int AqvmBaseLinkedList_AddNode(struct AqvmBaseLinkedList_LinkedList* list, void* data); -struct AqvmBaseLinkedList_LinkedList* AqvmBaseLinkedList_CreateLinkedList(); - int AqvmBaseLinkedList_CloseLinkedList( struct AqvmBaseLinkedList_LinkedList* list); @@ -33,6 +31,9 @@ int AqvmBaseLinkedList_DeleteNode(struct AqvmBaseLinkedList_LinkedList* list, void* AqvmBaseLinkedList_GetData(struct AqvmBaseLinkedList_LinkedList* list, size_t index); +int AqvmBaseLinkedList_InitializeLinkedList( + struct AqvmBaseLinkedList_LinkedList* linked_list); + int AqvmBaseLinkedList_InsertNode(struct AqvmBaseLinkedList_LinkedList* list, size_t index, void* data); diff --git a/aqvm/base/threading/file_lock/file_lock.c b/aqvm/base/threading/file_lock/file_lock.c index d8a15a8..c404649 100644 --- a/aqvm/base/threading/file_lock/file_lock.c +++ b/aqvm/base/threading/file_lock/file_lock.c @@ -2,4 +2,41 @@ // This program is licensed under the AQ License. You can find the AQ license in // the root directory. -#include "aqvm/base/threading/file_lock/file_lock.h" \ No newline at end of file +#include "aqvm/base/threading/file_lock/file_lock.h" + +#include "aqvm/base/file/file.h" +#include "aqvm/base/file/identifier/identifier.h" +#include "aqvm/base/file/read_write_lock/read_write_lock.h" +#include "aqvm/base/hash/table/table.h" +#include "aqvm/base/pair.h" + +struct AqvmBaseHashTable_HashTable AqvmBaseThreadingFileLock_fileLockTable; + +int AqvmBaseThreadingFileLock_CloseFileLockTable() { + if (AqvmBaseHashTable_CloseHashTable( + &AqvmBaseThreadingFileLock_fileLockTable) != 0) { + // TODO + return -1; + } + + return 0; +} + +int AqvmBaseThreadingFileLock_InitializeFileLockTable() { + if (AqvmBaseHashTable_InitializeHashTable( + &AqvmBaseThreadingFileLock_fileLockTable, 1024) != 0) { + return -1; + } + + return 0; +} + +int AqvmBaseThreadingFileLock_InsertFileLock(struct AqvmBaseFile_File* file) { + if (file == NULL) { + // TODO + return -1; + } + + AqvmBaseThreadingFileLock_fileLockTable + .data[AqvmBaseFileIdentifier_GetIdentifierHash(&file->identifier) % 1024]; +} \ No newline at end of file diff --git a/aqvm/base/threading/file_lock/file_lock.h b/aqvm/base/threading/file_lock/file_lock.h index b81b70c..90a6de8 100644 --- a/aqvm/base/threading/file_lock/file_lock.h +++ b/aqvm/base/threading/file_lock/file_lock.h @@ -5,4 +5,18 @@ #ifndef AQ_AQVM_BASE_THREADING_FILE_LOCK_FILE_LOCK_H_ #define AQ_AQVM_BASE_THREADING_FILE_LOCK_FILE_LOCK_H_ +#include "aqvm/base/file/file.h" +#include "aqvm/base/file/identifier/identifier.h" +#include "aqvm/base/file/read_write_lock/read_write_lock.h" +#include "aqvm/base/hash/table/table.h" + +extern struct AqvmBaseHashTable_HashTable + AqvmBaseThreadingFileLock_fileLockTable; + +int AqvmBaseThreadingFileLock_CloseFileLockTable(); + +int AqvmBaseThreadingFileLock_InitializeFileLockTable(); + +int AqvmBaseThreadingFileLock_InsertFileLock(struct AqvmBaseFile_File* file); + #endif \ No newline at end of file