POK(kernelpart)
/home/jaouen/pok_official/pok/trunk/kernel/middleware/portqueueingreceive.c
Go to the documentation of this file.
00001 /*
00002  *                               POK header
00003  * 
00004  * The following file is a part of the POK project. Any modification should
00005  * made according to the POK licence. You CANNOT use this file or a part of
00006  * this file is this part of a file for your own project
00007  *
00008  * For more information on the POK licence, please see our LICENCE FILE
00009  *
00010  * Please follow the coding guidelines described in doc/CODING_GUIDELINES
00011  *
00012  *                                      Copyright (c) 2007-2009 POK team 
00013  *
00014  * Created by julien on Thu Jan 15 23:34:13 2009 
00015  */
00016 
00017 #ifdef POK_NEEDS_PORTS_QUEUEING
00018 
00019 #include <types.h>
00020 #include <errno.h>
00021 
00022 #include <core/lockobj.h>
00023 #include <core/time.h>
00024 #include <core/sched.h>
00025 
00026 #include <middleware/port.h>
00027 #include <middleware/queue.h>
00028 
00029 #include <libc.h>
00030 
00031 extern pok_port_t    pok_ports[POK_CONFIG_NB_PORTS];
00032 
00033 pok_ret_t pok_port_queueing_receive (const pok_port_id_t    id, 
00034                                      uint64_t               timeout, 
00035                                      const pok_port_size_t  maxlen, 
00036                                      void*                  data, 
00037                                      pok_port_size_t*       len)
00038 {
00039 
00040    pok_port_size_t   clen;
00041    pok_port_size_t   rlen;
00042    pok_port_size_t   toclean;
00043    pok_ret_t ret;
00044 
00045    pok_lockobj_lockattr_t lockattr;
00046    (void) lockattr;
00047 
00048    *len = 0;
00049    if (maxlen <= 0)
00050    {
00051       return POK_ERRNO_EINVAL;
00052    }
00053 
00054    if (id > POK_CONFIG_NB_PORTS)
00055    {
00056       return POK_ERRNO_EINVAL;
00057    }
00058 
00059    if (! pok_own_port (POK_SCHED_CURRENT_PARTITION, id))
00060    {
00061       return POK_ERRNO_PORT;
00062    }
00063 
00064    if (pok_ports[id].ready != TRUE)
00065    {
00066 
00067       return POK_ERRNO_PORT;
00068    }
00069 
00070    if (pok_ports[id].kind != POK_PORT_KIND_QUEUEING)
00071    {
00072       return POK_ERRNO_KIND;
00073    }
00074 
00075    if (pok_ports[id].direction != POK_PORT_DIRECTION_IN)
00076    {
00077       return POK_ERRNO_DIRECTION;
00078    }
00079 
00080    toclean = maxlen;
00081    if (toclean > pok_ports[id].size)
00082    {
00083       toclean =  pok_ports[id].size;
00084    }
00085 
00086    /* Make sure we clean the data buffer before */
00087    memset (data, '\0', toclean);
00088 
00089    /*
00090     * TODO : check that the partition has the right
00091     * to receive anything
00092     */
00093 
00094    if (timeout > 0)
00095    {
00096       timeout = timeout + POK_GETTICK();
00097    }
00098 
00099    ret = pok_lockobj_lock (&pok_ports[id].lock, NULL);
00100 
00101    if (ret != POK_ERRNO_OK)
00102    {
00103       return ret;
00104    }
00105    while (pok_ports[id].empty == TRUE)
00106    {
00107       if (timeout == 0)
00108       {
00109          pok_lockobj_unlock (&pok_ports[id].lock, NULL);
00110          return POK_ERRNO_EMPTY;
00111       }
00112       else
00113       {
00114          ret = pok_lockobj_eventwait (&pok_ports[id].lock, timeout);
00115          if (ret != POK_ERRNO_OK)
00116          {
00117             pok_lockobj_unlock (&pok_ports[id].lock, NULL);
00118             return ret;
00119          }
00120       }
00121    }
00122 
00123    clen = pok_port_consumed_size (id);
00124 
00125    if (maxlen > clen )
00126    {
00127       rlen = clen;
00128    }
00129    else
00130    {
00131       rlen = maxlen;
00132    }
00133 
00134 
00135    if (pok_port_get (id, data, rlen) == POK_ERRNO_OK)
00136    {
00137       *len =  rlen;
00138    }
00139    else
00140    {
00141       *len = 0;
00142    }
00143 
00144    pok_lockobj_unlock (&pok_ports[id].lock, NULL);
00145 
00146    return POK_ERRNO_OK;
00147 }
00148 
00149 #endif