#define SPUFS_H
#include <linux/kref.h>
-#include <linux/rwsem.h>
+#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/fs.h>
struct spu_context_ops;
struct spu_gang;
+/* ctx->sched_flags */
+enum {
+ SPU_SCHED_EXITING = 0,
+};
+
struct spu_context {
struct spu *spu; /* pointer to a physical SPU */
struct spu_state csa; /* SPU context save area. */
spinlock_t mmio_lock; /* protects mmio access */
struct address_space *local_store; /* local store mapping. */
struct address_space *mfc; /* 'mfc' area mappings. */
- struct address_space *cntl; /* 'control' area mappings. */
- struct address_space *signal1; /* 'signal1' area mappings. */
- struct address_space *signal2; /* 'signal2' area mappings. */
- struct address_space *mss; /* 'mss' area mappings. */
- struct address_space *psmap; /* 'psmap' area mappings. */
+ struct address_space *cntl; /* 'control' area mappings. */
+ struct address_space *signal1; /* 'signal1' area mappings. */
+ struct address_space *signal2; /* 'signal2' area mappings. */
+ struct address_space *mss; /* 'mss' area mappings. */
+ struct address_space *psmap; /* 'psmap' area mappings. */
+ spinlock_t mapping_lock;
u64 object_id; /* user space pointer for oprofile */
enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state;
- struct rw_semaphore state_sema;
- struct semaphore run_sema;
+ struct mutex state_mutex;
+ struct mutex run_mutex;
struct mm_struct *owner;
struct list_head gang_list;
struct spu_gang *gang;
+
+ /* scheduler fields */
+ struct list_head rq;
+ struct delayed_work sched_work;
+ unsigned long sched_flags;
+ unsigned long rt_priority;
+ int policy;
+ int prio;
};
struct spu_gang {
struct spu_dma_info * info);
void (*proxydma_info_read) (struct spu_context * ctx,
struct spu_proxydma_info * info);
+ void (*restart_dma)(struct spu_context *ctx);
};
extern struct spu_context_ops spu_hw_ops;
struct spu_context *i_ctx;
struct spu_gang *i_gang;
struct inode vfs_inode;
+ int i_openers;
};
#define SPUFS_I(inode) \
container_of(inode, struct spufs_inode_info, vfs_inode)
void spu_gang_remove_ctx(struct spu_gang *gang, struct spu_context *ctx);
void spu_gang_add_ctx(struct spu_gang *gang, struct spu_context *ctx);
+/* fault handling */
+int spufs_handle_class1(struct spu_context *ctx);
+
/* context management */
+static inline void spu_acquire(struct spu_context *ctx)
+{
+ mutex_lock(&ctx->state_mutex);
+}
+
+static inline void spu_release(struct spu_context *ctx)
+{
+ mutex_unlock(&ctx->state_mutex);
+}
+
struct spu_context * alloc_spu_context(struct spu_gang *gang);
void destroy_spu_context(struct kref *kref);
struct spu_context * get_spu_context(struct spu_context *ctx);
void spu_unmap_mappings(struct spu_context *ctx);
void spu_forget(struct spu_context *ctx);
-void spu_acquire(struct spu_context *ctx);
-void spu_release(struct spu_context *ctx);
-int spu_acquire_runnable(struct spu_context *ctx);
+int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags);
void spu_acquire_saved(struct spu_context *ctx);
-int spu_acquire_exclusive(struct spu_context *ctx);
-static inline void spu_release_exclusive(struct spu_context *ctx)
-{
- up_write(&ctx->state_sema);
-}
-
-int spu_activate(struct spu_context *ctx, u64 flags);
+int spu_activate(struct spu_context *ctx, unsigned long flags);
void spu_deactivate(struct spu_context *ctx);
void spu_yield(struct spu_context *ctx);
+void spu_start_tick(struct spu_context *ctx);
+void spu_stop_tick(struct spu_context *ctx);
+void spu_sched_tick(struct work_struct *work);
int __init spu_sched_init(void);
void __exit spu_sched_exit(void);
prepare_to_wait(&(wq), &__wait, TASK_INTERRUPTIBLE); \
if (condition) \
break; \
- if (!signal_pending(current)) { \
- spu_release(ctx); \
- schedule(); \
- spu_acquire(ctx); \
- continue; \
+ if (signal_pending(current)) { \
+ __ret = -ERESTARTSYS; \
+ break; \
} \
- __ret = -ERESTARTSYS; \
- break; \
+ spu_release(ctx); \
+ schedule(); \
+ spu_acquire(ctx); \
} \
finish_wait(&(wq), &__wait); \
__ret; \