VirtualBox

source: vbox/trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_net.c@ 41971

Last change on this file since 41971 was 35845, checked in by vboxsync, 14 years ago

crOpenGL: proper deadlock fix for r69838

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.4 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "cr_pack.h"
8#include "cr_mem.h"
9#include "cr_net.h"
10#include "cr_pixeldata.h"
11#include "cr_protocol.h"
12#include "cr_error.h"
13#include "packspu.h"
14#include "packspu_proto.h"
15
16static void
17packspuWriteback( const CRMessageWriteback *wb )
18{
19 int *writeback;
20 crMemcpy( &writeback, &(wb->writeback_ptr), sizeof( writeback ) );
21 *writeback = 0;
22}
23
24/**
25 * XXX Note that this routine is identical to crNetRecvReadback except
26 * we set *writeback=0 instead of decrementing it. Hmmm.
27 */
28static void
29packspuReadback( const CRMessageReadback *rb, unsigned int len )
30{
31 /* minus the header, the destination pointer,
32 * *and* the implicit writeback pointer at the head. */
33
34 int payload_len = len - sizeof( *rb );
35 int *writeback;
36 void *dest_ptr;
37 crMemcpy( &writeback, &(rb->writeback_ptr), sizeof( writeback ) );
38 crMemcpy( &dest_ptr, &(rb->readback_ptr), sizeof( dest_ptr ) );
39
40 *writeback = 0;
41 crMemcpy( dest_ptr, ((char *)rb) + sizeof(*rb), payload_len );
42}
43
44static void
45packspuReadPixels( const CRMessageReadPixels *rp, unsigned int len )
46{
47 crNetRecvReadPixels( rp, len );
48 --pack_spu.ReadPixels;
49}
50
51static int
52packspuReceiveData( CRConnection *conn, CRMessage *msg, unsigned int len )
53{
54 if (msg->header.type == CR_MESSAGE_REDIR_PTR)
55 msg = (CRMessage*) msg->redirptr.pMessage;
56
57 switch( msg->header.type )
58 {
59 case CR_MESSAGE_READ_PIXELS:
60 packspuReadPixels( &(msg->readPixels), len );
61 break;
62 case CR_MESSAGE_WRITEBACK:
63 packspuWriteback( &(msg->writeback) );
64 break;
65 case CR_MESSAGE_READBACK:
66 packspuReadback( &(msg->readback), len );
67 break;
68 default:
69 /*crWarning( "Why is the pack SPU getting a message of type 0x%x?", msg->type ); */
70 return 0; /* NOT HANDLED */
71 }
72 return 1; /* HANDLED */
73}
74
75static CRMessageOpcodes *
76__prependHeader( CRPackBuffer *buf, unsigned int *len, unsigned int senderID )
77{
78 int num_opcodes;
79 CRMessageOpcodes *hdr;
80
81 CRASSERT( buf );
82 CRASSERT( buf->opcode_current < buf->opcode_start );
83 CRASSERT( buf->opcode_current >= buf->opcode_end );
84 CRASSERT( buf->data_current > buf->data_start );
85 CRASSERT( buf->data_current <= buf->data_end );
86
87 num_opcodes = buf->opcode_start - buf->opcode_current;
88 hdr = (CRMessageOpcodes *)
89 ( buf->data_start - ( ( num_opcodes + 3 ) & ~0x3 ) - sizeof(*hdr) );
90
91 CRASSERT( (void *) hdr >= buf->pack );
92
93 if (pack_spu.swap)
94 {
95 hdr->header.type = (CRMessageType) SWAP32(CR_MESSAGE_OPCODES);
96 hdr->numOpcodes = SWAP32(num_opcodes);
97 }
98 else
99 {
100 hdr->header.type = CR_MESSAGE_OPCODES;
101 hdr->numOpcodes = num_opcodes;
102 }
103
104 *len = buf->data_current - (unsigned char *) hdr;
105
106 return hdr;
107}
108
109
110/*
111 * This is called from either the Pack SPU and the packer library whenever
112 * we need to send a data buffer to the server.
113 */
114void packspuFlush(void *arg )
115{
116 ThreadInfo *thread = (ThreadInfo *) arg;
117 ContextInfo *ctx;
118 unsigned int len;
119 CRMessageOpcodes *hdr;
120 CRPackBuffer *buf;
121
122 /* we should _always_ pass a valid <arg> value */
123 CRASSERT(thread && thread->inUse);
124#ifdef CHROMIUM_THREADSAFE
125 CR_LOCK_PACKER_CONTEXT(thread->packer);
126#endif
127 ctx = thread->currentContext;
128 buf = &(thread->buffer);
129 CRASSERT(buf);
130
131 /* We're done packing into the current buffer, unbind it */
132 crPackReleaseBuffer( thread->packer );
133
134 /*
135 printf("%s thread=%p thread->id = %d thread->pc=%p t2->id=%d t2->pc=%p packbuf=%p packbuf=%p\n",
136 __FUNCTION__, (void*) thread, (int) thread->id, thread->packer,
137 (int) t2->id, t2->packer,
138 buf->pack, thread->packer->buffer.pack);
139 */
140
141 if ( buf->opcode_current == buf->opcode_start ) {
142 /*
143 printf("%s early return\n", __FUNCTION__);
144 */
145 /* XXX these calls seem to help, but might be appropriate */
146 crPackSetBuffer( thread->packer, buf );
147 crPackResetPointers(thread->packer);
148#ifdef CHROMIUM_THREADSAFE
149 CR_UNLOCK_PACKER_CONTEXT(thread->packer);
150#endif
151 return;
152 }
153
154 hdr = __prependHeader( buf, &len, 0 );
155
156 CRASSERT( thread->netServer.conn );
157
158 if ( buf->holds_BeginEnd )
159 {
160 /*crDebug("crNetBarf %d, (%d)", len, buf->size);*/
161 crNetBarf( thread->netServer.conn, &(buf->pack), hdr, len );
162 }
163 else
164 {
165 /*crDebug("crNetSend %d, (%d)", len, buf->size);*/
166 crNetSend( thread->netServer.conn, &(buf->pack), hdr, len );
167 }
168
169 buf->pack = crNetAlloc( thread->netServer.conn );
170
171 /* The network may have found a new mtu */
172 buf->mtu = thread->netServer.conn->mtu;
173
174 crPackSetBuffer( thread->packer, buf );
175
176 crPackResetPointers(thread->packer);
177
178#ifdef CHROMIUM_THREADSAFE
179 CR_UNLOCK_PACKER_CONTEXT(thread->packer);
180#endif
181}
182
183
184/**
185 * XXX NOTE: there's a lot of duplicate code here common to the
186 * pack, tilesort and replicate SPUs. Try to simplify someday!
187 */
188void packspuHuge( CROpcode opcode, void *buf )
189{
190 GET_THREAD(thread);
191 unsigned int len;
192 unsigned char *src;
193 CRMessageOpcodes *msg;
194
195 CRASSERT(thread);
196
197 /* packet length is indicated by the variable length field, and
198 includes an additional word for the opcode (with alignment) and
199 a header */
200 len = ((unsigned int *) buf)[-1];
201 if (pack_spu.swap)
202 {
203 /* It's already been swapped, swap it back. */
204 len = SWAP32(len);
205 }
206 len += 4 + sizeof(CRMessageOpcodes);
207
208 /* write the opcode in just before the length */
209 ((unsigned char *) buf)[-5] = (unsigned char) opcode;
210
211 /* fix up the pointer to the packet to include the length & opcode
212 & header */
213 src = (unsigned char *) buf - 8 - sizeof(CRMessageOpcodes);
214
215 msg = (CRMessageOpcodes *) src;
216
217 if (pack_spu.swap)
218 {
219 msg->header.type = (CRMessageType) SWAP32(CR_MESSAGE_OPCODES);
220 msg->numOpcodes = SWAP32(1);
221 }
222 else
223 {
224 msg->header.type = CR_MESSAGE_OPCODES;
225 msg->numOpcodes = 1;
226 }
227
228 CRASSERT( thread->netServer.conn );
229 crNetSend( thread->netServer.conn, NULL, src, len );
230}
231
232void packspuConnectToServer( CRNetServer *server )
233{
234 crNetInit( packspuReceiveData, NULL );
235 crNetServerConnect( server );
236}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette