Introduce new Lt
parent
9e7a466c79
commit
c8ad98bcee
|
@ -34,12 +34,9 @@ add_library(system STATIC
|
|||
src/system/log.h
|
||||
src/system/log_script.c
|
||||
src/system/log_script.h
|
||||
src/system/lt.c
|
||||
src/system/lt.h
|
||||
src/system/lt/lt_adapters.c
|
||||
src/system/lt/lt_adapters.h
|
||||
src/system/lt/lt_slot.c
|
||||
src/system/lt/lt_slot.h
|
||||
src/system/nth_alloc.c
|
||||
src/system/nth_alloc.h
|
||||
src/system/stacktrace.c
|
||||
|
|
126
src/system/lt.c
126
src/system/lt.c
|
@ -1,126 +0,0 @@
|
|||
#include "system/stacktrace.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lt.h"
|
||||
#include "lt/lt_slot.h"
|
||||
#include "system/nth_alloc.h"
|
||||
|
||||
#define INITIAL_FRAME_BUFFER_SIZE 16
|
||||
|
||||
struct Lt
|
||||
{
|
||||
Lt_slot **frames;
|
||||
size_t capacity;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
Lt *create_lt()
|
||||
{
|
||||
Lt *lt = nth_calloc(1, sizeof(Lt));
|
||||
if(lt == NULL) {
|
||||
goto nth_alloc_lt_fail;
|
||||
}
|
||||
|
||||
lt->frames = nth_calloc(1, sizeof(Lt_slot*) * INITIAL_FRAME_BUFFER_SIZE);
|
||||
if (lt->frames == NULL) {
|
||||
goto nth_alloc_lt_slots_fail;
|
||||
}
|
||||
|
||||
lt->capacity = INITIAL_FRAME_BUFFER_SIZE;
|
||||
lt->size = 0;
|
||||
|
||||
return lt;
|
||||
|
||||
nth_alloc_lt_slots_fail:
|
||||
free(lt);
|
||||
nth_alloc_lt_fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void destroy_lt(Lt *lt)
|
||||
{
|
||||
trace_assert(lt);
|
||||
|
||||
while (lt->size-- > 0) {
|
||||
if (lt->frames[lt->size]) {
|
||||
destroy_lt_slot(lt->frames[lt->size]);
|
||||
}
|
||||
}
|
||||
|
||||
free(lt->frames);
|
||||
free(lt);
|
||||
}
|
||||
|
||||
void *lt_push(Lt *lt, void *resource, Lt_destroy resource_destroy)
|
||||
{
|
||||
trace_assert(lt);
|
||||
trace_assert(resource_destroy);
|
||||
trace_assert(lt != resource);
|
||||
|
||||
if (resource == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (lt->size >= lt->capacity) {
|
||||
lt->capacity *= 2;
|
||||
if ((lt->frames = nth_realloc(lt->frames, sizeof(Lt_slot*) * lt->capacity)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((lt->frames[lt->size++] = create_lt_slot(resource, resource_destroy)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void* lt_reset(Lt *lt, void *old_resource, void *new_resource)
|
||||
{
|
||||
trace_assert(lt);
|
||||
trace_assert(old_resource);
|
||||
trace_assert(new_resource);
|
||||
trace_assert(old_resource != new_resource);
|
||||
|
||||
for (size_t i = 0; i < lt->size; ++i) {
|
||||
if (lt->frames[i] && lt_slot_contains_resource(lt->frames[i], old_resource)) {
|
||||
lt_slot_reset_resource(lt->frames[i], new_resource);
|
||||
return new_resource;
|
||||
}
|
||||
}
|
||||
|
||||
return old_resource;
|
||||
}
|
||||
|
||||
void *lt_release(Lt *lt, void *resource)
|
||||
{
|
||||
trace_assert(lt);
|
||||
trace_assert(resource);
|
||||
|
||||
for (size_t i = 0; i < lt->size; ++i) {
|
||||
if (lt->frames[i] && lt_slot_contains_resource(lt->frames[i], resource)) {
|
||||
release_lt_slot(lt->frames[i]);
|
||||
lt->frames[i] = NULL;
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void *lt_replace(Lt *lt, void *old_resource, void *new_resource)
|
||||
{
|
||||
trace_assert(lt);
|
||||
trace_assert(old_resource);
|
||||
trace_assert(new_resource);
|
||||
|
||||
for (size_t i = 0; i < lt->size; ++i) {
|
||||
if (lt->frames[i] && lt_slot_contains_resource(lt->frames[i], old_resource)) {
|
||||
lt_slot_replace_resource(lt->frames[i], new_resource);
|
||||
return new_resource;
|
||||
}
|
||||
}
|
||||
|
||||
return old_resource;
|
||||
}
|
130
src/system/lt.h
130
src/system/lt.h
|
@ -1,50 +1,112 @@
|
|||
#ifndef LT_H_
|
||||
#define LT_H_
|
||||
|
||||
#define PUSH_LT(lt, resource, resource_destroy) \
|
||||
lt_push(lt, (void*)resource, (Lt_destroy)resource_destroy)
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#define RESET_LT(lt, old_resource, new_resource) \
|
||||
lt_reset(lt, (void*)old_resource, (void*)new_resource)
|
||||
#define LT_INITIAL_CAPACITY 2
|
||||
|
||||
#define REPLACE_LT(lt, old_resource, new_resource) \
|
||||
lt_replace(lt, (void*)old_resource, (void*)new_resource)
|
||||
typedef void (*Dtor)(void*);
|
||||
|
||||
#define RELEASE_LT(lt, resource) \
|
||||
lt_release(lt, (void*) resource)
|
||||
typedef struct {
|
||||
void *res;
|
||||
Dtor dtor;
|
||||
} Slot;
|
||||
|
||||
#define RETURN_LT(lt, result) \
|
||||
do { \
|
||||
destroy_lt(lt); \
|
||||
return result; \
|
||||
} while (0)
|
||||
typedef struct {
|
||||
size_t size;
|
||||
size_t capacity;
|
||||
Slot *slots;
|
||||
} Lt;
|
||||
|
||||
#define RETURN_LT0(lt) \
|
||||
do { \
|
||||
destroy_lt(lt); \
|
||||
return; \
|
||||
} while (0)
|
||||
static inline void destroy_lt(Lt lt)
|
||||
{
|
||||
for (size_t i = lt.size; i > 0; --i) {
|
||||
if (lt.slots[i - 1].res) {
|
||||
lt.slots[i - 1].dtor(lt.slots[i - 1].res);
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct Lt Lt;
|
||||
typedef void (*Lt_destroy)(void*);
|
||||
free(lt.slots);
|
||||
}
|
||||
|
||||
Lt *create_lt(void);
|
||||
void destroy_lt(Lt *lt);
|
||||
#define PUSH_LT(lt, res, dtor) \
|
||||
lt_push(<, (void*)res, (Dtor)dtor)
|
||||
|
||||
/** \brief Pushes the resource onto the Life Time creating a new Life Time frame.
|
||||
*/
|
||||
void *lt_push(Lt *lt, void *resource, Lt_destroy resource_destroy);
|
||||
static inline void *lt_push(Lt *lt, void *res, Dtor dtor)
|
||||
{
|
||||
if (lt->size >= lt->capacity) {
|
||||
if (lt->capacity == 0) {
|
||||
lt->capacity = LT_INITIAL_CAPACITY;
|
||||
lt->slots = calloc(LT_INITIAL_CAPACITY, sizeof(Slot));
|
||||
} else {
|
||||
lt->capacity *= 2;
|
||||
lt->slots = realloc(lt->slots, lt->capacity * sizeof(Slot));
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Destroys old_resource preserving its LT frame and assigns the new_resource to the LT frame.
|
||||
*/
|
||||
void *lt_reset(Lt *lt, void *old_resource, void *new_resource);
|
||||
lt->slots[lt->size].res = res;
|
||||
lt->slots[lt->size].dtor = dtor;
|
||||
lt->size++;
|
||||
|
||||
/** \brief Replaces old_resource with new_resource in the LT frame without destroying old_resource.
|
||||
*/
|
||||
void *lt_replace(Lt *lt, void *old_resource, void *new_resource);
|
||||
return res;
|
||||
}
|
||||
|
||||
/** \brief Removes the LT frame of resource without destroying the resource.
|
||||
*/
|
||||
void *lt_release(Lt *lt, void *resource);
|
||||
#define RETURN_LT(lt, result) \
|
||||
return (destroy_lt(lt), result)
|
||||
|
||||
#define RETURN_LT0(lt) (destroy_lt(lt), return)
|
||||
|
||||
#define RESET_LT(lt, old_res, new_res) \
|
||||
lt_reset(<, (void*) old_res, (void*) new_res)
|
||||
|
||||
static inline void *lt_reset(Lt *lt, void *old_res, void *new_res)
|
||||
{
|
||||
assert(old_res != new_res);
|
||||
|
||||
for (size_t i = 0; i < lt->size; ++i) {
|
||||
if (lt->slots[i].res == old_res) {
|
||||
lt->slots[i].dtor(old_res);
|
||||
lt->slots[i].res = new_res;
|
||||
return new_res;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#define REPLACE_LT(lt, old_res, new_res) \
|
||||
lt_replace(<, (void *)old_res, (void*)new_res)
|
||||
|
||||
static inline void *lt_replace(Lt *lt, void *old_res, void *new_res)
|
||||
{
|
||||
for (size_t i = 0; i < lt->size; ++i) {
|
||||
if (lt->slots[i].res == old_res) {
|
||||
lt->slots[i].res = new_res;
|
||||
return new_res;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define RELEASE_LT(lt, res) \
|
||||
lt_release(<, (void*)res)
|
||||
|
||||
static inline void *lt_release(Lt *lt, void *res)
|
||||
{
|
||||
for (size_t i = 0; i < lt->size; ++i) {
|
||||
if (lt->slots[i].res == res) {
|
||||
memmove(
|
||||
<->slots[i],
|
||||
<->slots[i + 1],
|
||||
(lt->size - i - 1) * sizeof(Slot));
|
||||
lt->size--;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif // LT_H_
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
#include "system/stacktrace.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lt_slot.h"
|
||||
#include "system/nth_alloc.h"
|
||||
|
||||
struct Lt_slot
|
||||
{
|
||||
void *resource;
|
||||
Lt_destroy resource_destroy;
|
||||
};
|
||||
|
||||
Lt_slot *create_lt_slot(void *resource, Lt_destroy resource_destroy)
|
||||
{
|
||||
trace_assert(resource);
|
||||
trace_assert(resource_destroy);
|
||||
|
||||
Lt_slot *lt_slot = nth_calloc(1, sizeof(Lt_slot));
|
||||
if (lt_slot == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lt_slot->resource = resource;
|
||||
lt_slot->resource_destroy = resource_destroy;
|
||||
|
||||
return lt_slot;
|
||||
}
|
||||
|
||||
void *release_lt_slot(Lt_slot *lt_slot)
|
||||
{
|
||||
trace_assert(lt_slot);
|
||||
|
||||
void *resource = lt_slot->resource;
|
||||
free(lt_slot);
|
||||
return resource;
|
||||
}
|
||||
|
||||
void destroy_lt_slot(Lt_slot *lt_slot)
|
||||
{
|
||||
trace_assert(lt_slot);
|
||||
|
||||
lt_slot->resource_destroy(lt_slot->resource);
|
||||
free(lt_slot);
|
||||
}
|
||||
|
||||
void lt_slot_reset_resource(Lt_slot *lt_slot, void *resource)
|
||||
{
|
||||
trace_assert(lt_slot);
|
||||
trace_assert(resource);
|
||||
|
||||
lt_slot->resource_destroy(lt_slot->resource);
|
||||
lt_slot->resource = resource;
|
||||
}
|
||||
|
||||
void lt_slot_replace_resource(Lt_slot *lt_slot, void *resource)
|
||||
{
|
||||
trace_assert(lt_slot);
|
||||
trace_assert(resource);
|
||||
|
||||
lt_slot->resource = resource;
|
||||
}
|
||||
|
||||
int lt_slot_contains_resource(const Lt_slot *lt_slot, void *resource)
|
||||
{
|
||||
trace_assert(lt_slot);
|
||||
trace_assert(resource);
|
||||
|
||||
return lt_slot->resource == resource;
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
#ifndef LT_SLOT_H_
|
||||
#define LT_SLOT_H_
|
||||
|
||||
#include "../lt.h"
|
||||
|
||||
typedef struct Lt_slot Lt_slot;
|
||||
|
||||
Lt_slot *create_lt_slot(void *resource, Lt_destroy resource_destroy);
|
||||
void *release_lt_slot(Lt_slot *lt_slot);
|
||||
void destroy_lt_slot(Lt_slot *lt_slot);
|
||||
|
||||
void lt_slot_reset_resource(Lt_slot *lt_slot, void *resource);
|
||||
void lt_slot_replace_resource(Lt_slot *lt_slot, void *resource);
|
||||
int lt_slot_contains_resource(const Lt_slot *lt_slot, void *resource);
|
||||
|
||||
#endif // LT_SLOT_H_
|
Loading…
Reference in New Issue