cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

pool.c (3519B)


      1/*
      2 * Licensed to the Apache Software Foundation (ASF) under one
      3 * or more contributor license agreements.  See the NOTICE file
      4 * distributed with this work for additional information
      5 * regarding copyright ownership.  The ASF licenses this file
      6 * to you under the Apache License, Version 2.0 (the
      7 * "License"); you may not use this file except in compliance
      8 * with the License.  You may obtain a copy of the License at
      9 *
     10 *   http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing,
     13 * software distributed under the License is distributed on an
     14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     15 * KIND, either express or implied.  See the License for the
     16 * specific language governing permissions and limitations
     17 * under the License.
     18 */
     19
     20#include "config.h"
     21
     22#include "guacamole/mem.h"
     23#include "guacamole/pool.h"
     24
     25#include <stdlib.h>
     26
     27guac_pool* guac_pool_alloc(int size) {
     28
     29    pthread_mutexattr_t lock_attributes;
     30    guac_pool* pool = guac_mem_alloc(sizeof(guac_pool));
     31
     32    /* If unable to allocate, just return NULL. */
     33    if (pool == NULL)
     34        return NULL;
     35
     36    /* Initialize empty pool */
     37    pool->min_size = size;
     38    pool->active = 0;
     39    pool->__next_value = 0;
     40    pool->__head = NULL;
     41    pool->__tail = NULL;
     42
     43    /* Init lock */
     44    pthread_mutexattr_init(&lock_attributes);
     45    pthread_mutexattr_setpshared(&lock_attributes, PTHREAD_PROCESS_SHARED);
     46    pthread_mutex_init(&(pool->__lock), &lock_attributes);
     47
     48    return pool;
     49
     50}
     51
     52void guac_pool_free(guac_pool* pool) {
     53
     54    /* Free all ints in pool */
     55    guac_pool_int* current = pool->__head;
     56    while (current != NULL) {
     57
     58        guac_pool_int* old = current;
     59        current = current->__next;
     60
     61        guac_mem_free(old);
     62    }
     63
     64    /* Destroy lock */
     65    pthread_mutex_destroy(&(pool->__lock));
     66
     67    /* Free pool */
     68    guac_mem_free(pool);
     69
     70}
     71
     72int guac_pool_next_int(guac_pool* pool) {
     73
     74    int value;
     75
     76    /* Acquire exclusive access */
     77    pthread_mutex_lock(&(pool->__lock));
     78
     79    pool->active++;
     80
     81    /* If more integers are needed, return a new one. */
     82    if (pool->__head == NULL || pool->__next_value < pool->min_size) {
     83        value = pool->__next_value++;
     84        pthread_mutex_unlock(&(pool->__lock));
     85        return value;
     86    }
     87
     88    /* Otherwise, remove first integer. */
     89    value = pool->__head->value;
     90
     91    /* If only one element exists, reset pool to empty. */
     92    if (pool->__tail == pool->__head) {
     93        guac_mem_free(pool->__head);
     94        pool->__head = NULL;
     95        pool->__tail = NULL;
     96    }
     97
     98    /* Otherwise, advance head. */
     99    else {
    100        guac_pool_int* old_head = pool->__head;
    101        pool->__head = old_head->__next;
    102        guac_mem_free(old_head);
    103    }
    104
    105    /* Return retrieved value. */
    106    pthread_mutex_unlock(&(pool->__lock));
    107    return value;
    108}
    109
    110void guac_pool_free_int(guac_pool* pool, int value) {
    111
    112    /* Allocate and initialize new returned value */
    113    guac_pool_int* pool_int = guac_mem_alloc(sizeof(guac_pool_int));
    114    pool_int->value = value;
    115    pool_int->__next = NULL;
    116
    117    /* Acquire exclusive access */
    118    pthread_mutex_lock(&(pool->__lock));
    119
    120    pool->active--;
    121
    122    /* If pool empty, store as sole entry. */
    123    if (pool->__tail == NULL)
    124        pool->__head = pool->__tail = pool_int;
    125
    126    /* Otherwise, append to end of pool. */
    127    else {
    128        pool->__tail->__next = pool_int;
    129        pool->__tail = pool_int;
    130    }
    131
    132    /* Value has been freed */
    133    pthread_mutex_unlock(&(pool->__lock));
    134
    135}
    136