⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fusionee.c

📁 linux下的fusion程序,可以和directfb配合使用
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *	Fusion Kernel Module * *	(c) Copyright 2002-2003  Convergence GmbH * *      Written by Denis Oliver Kropp <dok@directfb.org> * * *	This program is free software; you can redistribute it and/or *	modify it under the terms of the GNU General Public License *	as published by the Free Software Foundation; either version *	2 of the License, or (at your option) any later version. */#ifdef HAVE_LINUX_CONFIG_H#include <linux/config.h>#endif#include <linux/version.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/slab.h>#include <linux/smp_lock.h>#include <linux/sched.h>#include <asm/uaccess.h>#include <linux/fusion.h>#include "call.h"#include "fifo.h"#include "list.h"#include "fusiondev.h"#include "fusionee.h"#include "property.h"#include "reactor.h"#include "ref.h"#include "skirmish.h"#include "shmpool.h"#if 0#define DEBUG(x...)  printk (KERN_DEBUG "Fusion: " x)#else#define DEBUG(x...)  do {} while (0)#endifstruct __Fusion_Fusionee {     FusionLink        link;     struct semaphore  lock;     FusionID          id;     int               pid;     FusionFifo        messages;     FusionFifo        prev_msgs;     int               rcv_total;  /* Total number of messages received. */     int               snd_total;  /* Total number of messages sent. */     wait_queue_head_t wait;     bool              force_slave;     struct mm_struct *mm;};typedef struct {     FusionLink         link;     FusionMessageType  type;     int                id;     int                channel;     int                size;     void              *data;     MessageCallback    callback;     void              *callback_ctx;     int                callback_param;} Message;/******************************************************************************/static int  lookup_fusionee (FusionDev *dev, FusionID id, Fusionee **ret_fusionee);static int  lock_fusionee   (FusionDev *dev, FusionID id, Fusionee **ret_fusionee);static void unlock_fusionee (Fusionee *fusionee);static void flush_messages  (FusionDev *dev, FusionFifo *fifo);/******************************************************************************/static intfusionees_read_proc(char *buf, char **start, off_t offset,                    int len, int *eof, void *private){     FusionLink *l;     FusionDev  *dev     = private;     int         written = 0;     if (down_interruptible (&dev->fusionee.lock))          return -EINTR;     fusion_list_foreach (l, dev->fusionee.list) {          Fusionee *fusionee = (Fusionee*) l;          written += sprintf(buf+written, "(%5d) 0x%08lx (%4d messages waiting, %7d received, %7d sent)\n",                             fusionee->pid, fusionee->id, fusionee->messages.count, fusionee->rcv_total, fusionee->snd_total);          if (written < offset) {               offset -= written;               written = 0;          }          if (written >= len)               break;     }     up (&dev->fusionee.lock);     *start = buf + offset;     written -= offset;     if (written > len) {          *eof = 0;          return len;     }     *eof = 1;     return(written<0) ? 0 : written;}intfusionee_init (FusionDev *dev){     init_waitqueue_head (&dev->fusionee.wait);     init_MUTEX (&dev->fusionee.lock);     create_proc_read_entry("fusionees", 0, dev->proc_dir,                            fusionees_read_proc, dev);     return 0;}voidfusionee_deinit (FusionDev *dev){     FusionLink *l;     down (&dev->fusionee.lock);     remove_proc_entry ("fusionees", dev->proc_dir);     l = dev->fusionee.list;     while (l) {          FusionLink *next     = l->next;          Fusionee   *fusionee = (Fusionee *) l;          while (fusionee->messages.count) {               Message *message = (Message*) fusion_fifo_get (&fusionee->messages);               kfree (message);          }          kfree (fusionee);          l = next;     }     up (&dev->fusionee.lock);}/******************************************************************************/intfusionee_new( FusionDev  *dev,              bool        force_slave,              Fusionee  **ret_fusionee ){     Fusionee *fusionee;     fusionee = kmalloc (sizeof(Fusionee), GFP_KERNEL);     if (!fusionee)          return -ENOMEM;     memset (fusionee, 0, sizeof(Fusionee));     if (down_interruptible (&dev->fusionee.lock)) {          kfree (fusionee);          return -EINTR;     }     fusionee->pid         = current->pid;     fusionee->force_slave = force_slave;     fusionee->mm          = current->mm;     init_MUTEX (&fusionee->lock);     init_waitqueue_head (&fusionee->wait);     fusion_list_prepend (&dev->fusionee.list, &fusionee->link);     up (&dev->fusionee.lock);     *ret_fusionee = fusionee;     return 0;}intfusionee_enter( FusionDev   *dev,                FusionEnter *enter,                Fusionee    *fusionee ){     if (enter->api.major != FUSION_API_MAJOR || enter->api.minor > FUSION_API_MINOR)          return -ENOPROTOOPT;     if (down_interruptible( &dev->enter_lock ))          return -EINTR;     if (dev->fusionee.last_id || fusionee->force_slave) {          while (!dev->enter_ok) {               fusion_sleep_on( &dev->enter_wait, &dev->enter_lock, NULL );               if (signal_pending(current))                    return -EINTR;               if (down_interruptible( &dev->enter_lock ))                    return -EINTR;          }          FUSION_ASSERT( dev->fusionee.last_id != 0 );     }     fusionee->id = ++dev->fusionee.last_id;     up( &dev->enter_lock );     enter->fusion_id = fusionee->id;     return 0;}intfusionee_fork( FusionDev  *dev,               FusionFork *fork,               Fusionee   *fusionee ){     int ret;     ret = fusion_shmpool_fork_all( dev, fusionee->id, fork->fusion_id );     if (ret)          return ret;     ret = fusion_reactor_fork_all( dev, fusionee->id, fork->fusion_id );     if (ret)          return ret;     ret = fusion_ref_fork_all_local( dev, fusionee->id, fork->fusion_id );     if (ret)          return ret;     fork->fusion_id = fusionee->id;     return 0;}intfusionee_send_message( FusionDev         *dev,                       Fusionee          *sender,                       FusionID           recipient,                       FusionMessageType  msg_type,                       int                msg_id,                       int                msg_channel,                       int                msg_size,                       const void        *msg_data,                       MessageCallback    callback,                       void              *callback_ctx,                       int                callback_param ){     int       ret;     Message  *message;     Fusionee *fusionee;     DEBUG( "fusionee_send_message (%d -> %d, type %d, id %d, size %d)\n",            fusionee->id, recipient, msg_type, msg_id, msg_size );     ret = lookup_fusionee (dev, recipient, &fusionee);     if (ret)          return ret;     if (down_interruptible (&fusionee->lock)) {          up (&dev->fusionee.lock);          return -EINTR;     }     if (sender && sender != fusionee) {          if (down_interruptible (&sender->lock)) {               unlock_fusionee (fusionee);               up (&dev->fusionee.lock);               return -EINTR;          }     }     up (&dev->fusionee.lock);     message = kmalloc (sizeof(Message) + msg_size, GFP_KERNEL);     if (!message) {          if (sender && sender != fusionee)               unlock_fusionee (sender);          unlock_fusionee (fusionee);          return -ENOMEM;     }     message->data = message + 1;     if (msg_type == FMT_CALL || msg_type == FMT_SHMPOOL)          memcpy (message->data, msg_data, msg_size);     else if (copy_from_user (message->data, msg_data, msg_size)) {          kfree (message);          if (sender && sender != fusionee)               unlock_fusionee (sender);          unlock_fusionee (fusionee);          return -EFAULT;     }     message->type           = msg_type;     message->id             = msg_id;     message->channel        = msg_channel;     message->size           = msg_size;     message->callback       = callback;     message->callback_ctx   = callback_ctx;     message->callback_param = callback_param;     fusion_fifo_put (&fusionee->messages, &message->link);     fusionee->rcv_total++;     if (sender)          sender->snd_total++;     wake_up_interruptible_all (&fusionee->wait);     if (sender && sender != fusionee)          unlock_fusionee (sender);     unlock_fusionee (fusionee);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -