cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

intlist.c (3144B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Based on intlist.c by:
      4 * (c) 2009 Arnaldo Carvalho de Melo <acme@redhat.com>
      5 */
      6
      7#include <errno.h>
      8#include <stdlib.h>
      9#include <linux/compiler.h>
     10
     11#include "intlist.h"
     12
     13static struct rb_node *intlist__node_new(struct rblist *rblist __maybe_unused,
     14					 const void *entry)
     15{
     16	unsigned long i = (unsigned long)entry;
     17	struct rb_node *rc = NULL;
     18	struct int_node *node = malloc(sizeof(*node));
     19
     20	if (node != NULL) {
     21		node->i = i;
     22		node->priv = NULL;
     23		rc = &node->rb_node;
     24	}
     25
     26	return rc;
     27}
     28
     29static void int_node__delete(struct int_node *ilist)
     30{
     31	free(ilist);
     32}
     33
     34static void intlist__node_delete(struct rblist *rblist __maybe_unused,
     35				 struct rb_node *rb_node)
     36{
     37	struct int_node *node = container_of(rb_node, struct int_node, rb_node);
     38
     39	int_node__delete(node);
     40}
     41
     42static int intlist__node_cmp(struct rb_node *rb_node, const void *entry)
     43{
     44	unsigned long i = (unsigned long)entry;
     45	struct int_node *node = container_of(rb_node, struct int_node, rb_node);
     46
     47	if (node->i > i)
     48		return 1;
     49	else if (node->i < i)
     50		return -1;
     51
     52	return 0;
     53}
     54
     55int intlist__add(struct intlist *ilist, unsigned long i)
     56{
     57	return rblist__add_node(&ilist->rblist, (void *)i);
     58}
     59
     60void intlist__remove(struct intlist *ilist, struct int_node *node)
     61{
     62	rblist__remove_node(&ilist->rblist, &node->rb_node);
     63}
     64
     65static struct int_node *__intlist__findnew(struct intlist *ilist,
     66					   unsigned long i, bool create)
     67{
     68	struct int_node *node = NULL;
     69	struct rb_node *rb_node;
     70
     71	if (ilist == NULL)
     72		return NULL;
     73
     74	if (create)
     75		rb_node = rblist__findnew(&ilist->rblist, (void *)i);
     76	else
     77		rb_node = rblist__find(&ilist->rblist, (void *)i);
     78
     79	if (rb_node)
     80		node = container_of(rb_node, struct int_node, rb_node);
     81
     82	return node;
     83}
     84
     85struct int_node *intlist__find(struct intlist *ilist, unsigned long i)
     86{
     87	return __intlist__findnew(ilist, i, false);
     88}
     89
     90struct int_node *intlist__findnew(struct intlist *ilist, unsigned long i)
     91{
     92	return __intlist__findnew(ilist, i, true);
     93}
     94
     95static int intlist__parse_list(struct intlist *ilist, const char *s)
     96{
     97	char *sep;
     98	int err;
     99
    100	do {
    101		unsigned long value = strtol(s, &sep, 10);
    102		err = -EINVAL;
    103		if (*sep != ',' && *sep != '\0')
    104			break;
    105		err = intlist__add(ilist, value);
    106		if (err)
    107			break;
    108		s = sep + 1;
    109	} while (*sep != '\0');
    110
    111	return err;
    112}
    113
    114struct intlist *intlist__new(const char *slist)
    115{
    116	struct intlist *ilist = malloc(sizeof(*ilist));
    117
    118	if (ilist != NULL) {
    119		rblist__init(&ilist->rblist);
    120		ilist->rblist.node_cmp    = intlist__node_cmp;
    121		ilist->rblist.node_new    = intlist__node_new;
    122		ilist->rblist.node_delete = intlist__node_delete;
    123
    124		if (slist && intlist__parse_list(ilist, slist))
    125			goto out_delete;
    126	}
    127
    128	return ilist;
    129out_delete:
    130	intlist__delete(ilist);
    131	return NULL;
    132}
    133
    134void intlist__delete(struct intlist *ilist)
    135{
    136	if (ilist != NULL)
    137		rblist__delete(&ilist->rblist);
    138}
    139
    140struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx)
    141{
    142	struct int_node *node = NULL;
    143	struct rb_node *rb_node;
    144
    145	rb_node = rblist__entry(&ilist->rblist, idx);
    146	if (rb_node)
    147		node = container_of(rb_node, struct int_node, rb_node);
    148
    149	return node;
    150}