0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/list.h>
0011 #include <linux/slab.h>
0012
0013 #include "spufs.h"
0014
0015 struct spu_gang *alloc_spu_gang(void)
0016 {
0017 struct spu_gang *gang;
0018
0019 gang = kzalloc(sizeof *gang, GFP_KERNEL);
0020 if (!gang)
0021 goto out;
0022
0023 kref_init(&gang->kref);
0024 mutex_init(&gang->mutex);
0025 mutex_init(&gang->aff_mutex);
0026 INIT_LIST_HEAD(&gang->list);
0027 INIT_LIST_HEAD(&gang->aff_list_head);
0028
0029 out:
0030 return gang;
0031 }
0032
0033 static void destroy_spu_gang(struct kref *kref)
0034 {
0035 struct spu_gang *gang;
0036 gang = container_of(kref, struct spu_gang, kref);
0037 WARN_ON(gang->contexts || !list_empty(&gang->list));
0038 kfree(gang);
0039 }
0040
0041 struct spu_gang *get_spu_gang(struct spu_gang *gang)
0042 {
0043 kref_get(&gang->kref);
0044 return gang;
0045 }
0046
0047 int put_spu_gang(struct spu_gang *gang)
0048 {
0049 return kref_put(&gang->kref, &destroy_spu_gang);
0050 }
0051
0052 void spu_gang_add_ctx(struct spu_gang *gang, struct spu_context *ctx)
0053 {
0054 mutex_lock(&gang->mutex);
0055 ctx->gang = get_spu_gang(gang);
0056 list_add(&ctx->gang_list, &gang->list);
0057 gang->contexts++;
0058 mutex_unlock(&gang->mutex);
0059 }
0060
0061 void spu_gang_remove_ctx(struct spu_gang *gang, struct spu_context *ctx)
0062 {
0063 mutex_lock(&gang->mutex);
0064 WARN_ON(ctx->gang != gang);
0065 if (!list_empty(&ctx->aff_list)) {
0066 list_del_init(&ctx->aff_list);
0067 gang->aff_flags &= ~AFF_OFFSETS_SET;
0068 }
0069 list_del_init(&ctx->gang_list);
0070 gang->contexts--;
0071 mutex_unlock(&gang->mutex);
0072
0073 put_spu_gang(gang);
0074 }