Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
f34a6cd8
Commit
f34a6cd8
authored
Dec 29, 2010
by
antirez
Browse files
still more work for diskstore
parent
f2da3a62
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/dscache.c
View file @
f34a6cd8
...
@@ -107,13 +107,13 @@
...
@@ -107,13 +107,13 @@
* as a fully non-blocking VM.
* as a fully non-blocking VM.
*/
*/
void
spawnIOThread
(
void
);
/* =================== Virtual Memory - Blocking Side ====================== */
/* =================== Virtual Memory - Blocking Side ====================== */
void
dsInit
(
void
)
{
void
dsInit
(
void
)
{
off_t
totsize
;
int
pipefds
[
2
];
int
pipefds
[
2
];
size_t
stacksize
;
size_t
stacksize
;
struct
flock
fl
;
zmalloc_enable_thread_safeness
();
/* we need thread safe zmalloc() */
zmalloc_enable_thread_safeness
();
/* we need thread safe zmalloc() */
...
@@ -239,42 +239,22 @@ int dsCanTouchDiskStore(void) {
...
@@ -239,42 +239,22 @@ int dsCanTouchDiskStore(void) {
/* =================== Virtual Memory - Threaded I/O ======================= */
/* =================== Virtual Memory - Threaded I/O ======================= */
void
freeIOJob
(
iojob
*
j
)
{
void
freeIOJob
(
iojob
*
j
)
{
if
((
j
->
type
==
REDIS_IOJOB_PREPARE_SWAP
||
j
->
type
==
REDIS_IOJOB_DO_SWAP
||
j
->
type
==
REDIS_IOJOB_LOAD
)
&&
j
->
val
!=
NULL
)
{
/* we fix the storage type, otherwise decrRefCount() will try to
* kill the I/O thread Job (that does no longer exists). */
if
(
j
->
val
->
storage
==
REDIS_VM_SWAPPING
)
j
->
val
->
storage
=
REDIS_VM_MEMORY
;
decrRefCount
(
j
->
val
);
}
decrRefCount
(
j
->
key
);
decrRefCount
(
j
->
key
);
zfree
(
j
);
zfree
(
j
);
}
}
/* Every time a thread finished a Job, it writes a byte into the write side
/* Every time a thread finished a Job, it writes a byte into the write side
* of an unix pipe in order to "awake" the main thread, and this function
* of an unix pipe in order to "awake" the main thread, and this function
* is called.
* is called. */
*
* Note that this is called both by the event loop, when a I/O thread
* sends a byte in the notification pipe, and is also directly called from
* waitEmptyIOJobsQueue().
*
* In the latter case we don't want to swap more, so we use the
* "privdata" argument setting it to a not NULL value to signal this
* condition. */
void
vmThreadedIOCompletedJob
(
aeEventLoop
*
el
,
int
fd
,
void
*
privdata
,
void
vmThreadedIOCompletedJob
(
aeEventLoop
*
el
,
int
fd
,
void
*
privdata
,
int
mask
)
int
mask
)
{
{
char
buf
[
1
];
char
buf
[
1
];
int
retval
,
processed
=
0
,
toprocess
=
-
1
,
trytoswap
=
1
;
int
retval
,
processed
=
0
,
toprocess
=
-
1
;
REDIS_NOTUSED
(
el
);
REDIS_NOTUSED
(
el
);
REDIS_NOTUSED
(
mask
);
REDIS_NOTUSED
(
mask
);
REDIS_NOTUSED
(
privdata
);
REDIS_NOTUSED
(
privdata
);
if
(
privdata
!=
NULL
)
trytoswap
=
0
;
/* check the comments above... */
/* For every byte we read in the read side of the pipe, there is one
/* For every byte we read in the read side of the pipe, there is one
* I/O job completed to process. */
* I/O job completed to process. */
while
((
retval
=
read
(
fd
,
buf
,
1
))
==
1
)
{
while
((
retval
=
read
(
fd
,
buf
,
1
))
==
1
)
{
...
@@ -295,11 +275,7 @@ void vmThreadedIOCompletedJob(aeEventLoop *el, int fd, void *privdata,
...
@@ -295,11 +275,7 @@ void vmThreadedIOCompletedJob(aeEventLoop *el, int fd, void *privdata,
j
=
ln
->
value
;
j
=
ln
->
value
;
listDelNode
(
server
.
io_processed
,
ln
);
listDelNode
(
server
.
io_processed
,
ln
);
unlockThreadedIO
();
unlockThreadedIO
();
/* If this job is marked as canceled, just ignore it */
if
(
j
->
canceled
)
{
freeIOJob
(
j
);
continue
;
}
/* Post process it in the main thread, as there are things we
/* Post process it in the main thread, as there are things we
* can do just here to avoid race conditions and/or invasive locks */
* can do just here to avoid race conditions and/or invasive locks */
redisLog
(
REDIS_DEBUG
,
"COMPLETED Job type: %d, ID %p, key: %s"
,
j
->
type
,
(
void
*
)
j
->
id
,
(
unsigned
char
*
)
j
->
key
->
ptr
);
redisLog
(
REDIS_DEBUG
,
"COMPLETED Job type: %d, ID %p, key: %s"
,
j
->
type
,
(
void
*
)
j
->
id
,
(
unsigned
char
*
)
j
->
key
->
ptr
);
...
@@ -322,27 +298,6 @@ void vmThreadedIOCompletedJob(aeEventLoop *el, int fd, void *privdata,
...
@@ -322,27 +298,6 @@ void vmThreadedIOCompletedJob(aeEventLoop *el, int fd, void *privdata,
handleClientsBlockedOnSwappedKey
(
db
,
j
->
key
);
handleClientsBlockedOnSwappedKey
(
db
,
j
->
key
);
freeIOJob
(
j
);
freeIOJob
(
j
);
zfree
(
vp
);
zfree
(
vp
);
}
else
if
(
j
->
type
==
REDIS_IOJOB_PREPARE_SWAP
)
{
/* Now we know the amount of pages required to swap this object.
* Let's find some space for it, and queue this task again
* rebranded as REDIS_IOJOB_DO_SWAP. */
if
(
!
vmCanSwapOut
()
||
vmFindContiguousPages
(
&
j
->
page
,
j
->
pages
)
==
REDIS_ERR
)
{
/* Ooops... no space or we can't swap as there is
* a fork()ed Redis trying to save stuff on disk. */
j
->
val
->
storage
=
REDIS_VM_MEMORY
;
/* undo operation */
freeIOJob
(
j
);
}
else
{
/* Note that we need to mark this pages as used now,
* if the job will be canceled, we'll mark them as freed
* again. */
vmMarkPagesUsed
(
j
->
page
,
j
->
pages
);
j
->
type
=
REDIS_IOJOB_DO_SWAP
;
lockThreadedIO
();
queueIOJob
(
j
);
unlockThreadedIO
();
}
}
else
if
(
j
->
type
==
REDIS_IOJOB_DO_SWAP
)
{
}
else
if
(
j
->
type
==
REDIS_IOJOB_DO_SWAP
)
{
vmpointer
*
vp
;
vmpointer
*
vp
;
...
...
src/redis.h
View file @
f34a6cd8
...
@@ -125,6 +125,7 @@
...
@@ -125,6 +125,7 @@
#define REDIS_DS_SAVING 2
/* There is an IO Job created for this obj. */
#define REDIS_DS_SAVING 2
/* There is an IO Job created for this obj. */
#define REDIS_MAX_COMPLETED_JOBS_PROCESSED 1
#define REDIS_MAX_COMPLETED_JOBS_PROCESSED 1
#define REDIS_THREAD_STACK_SIZE (1024*1024*4)
/* Client flags */
/* Client flags */
#define REDIS_SLAVE 1
/* This client is a slave server */
#define REDIS_SLAVE 1
/* This client is a slave server */
...
@@ -542,22 +543,15 @@ typedef struct zset {
...
@@ -542,22 +543,15 @@ typedef struct zset {
}
zset
;
}
zset
;
/* VM threaded I/O request message */
/* VM threaded I/O request message */
#define REDIS_IOJOB_LOAD 0
/* Load from disk to memory */
#define REDIS_IOJOB_LOAD 0
#define REDIS_IOJOB_
PREPARE_SWAP 1
/* Compute needed pages */
#define REDIS_IOJOB_
SAVE 1
#define REDIS_IOJOB_DO_SWAP 2
/* Swap from memory to disk */
typedef
struct
iojob
{
typedef
struct
iojob
{
int
type
;
/* Request type, REDIS_IOJOB_* */
int
type
;
/* Request type, REDIS_IOJOB_* */
redisDb
*
db
;
/* Redis database */
redisDb
*
db
;
/* Redis database */
robj
*
key
;
/* This I/O request is about swapping this key */
robj
*
key
;
/* This I/O request is about this key */
robj
*
id
;
/* Unique identifier of this job:
robj
*
val
;
/* the value to swap for REDIS_IOJOB_SAVE, otherwise this
this is the object to swap for REDIS_IOREQ_*_SWAP, or the
* field is populated by the I/O thread for REDIS_IOJOB_LOAD. */
vmpointer objct for REDIS_IOREQ_LOAD. */
robj
*
val
;
/* the value to swap for REDIS_IOREQ_*_SWAP, otherwise this
* field is populated by the I/O thread for REDIS_IOREQ_LOAD. */
off_t
page
;
/* Swap page where to read/write the object */
off_t
pages
;
/* Swap pages needed to save object. PREPARE_SWAP return val */
int
canceled
;
/* True if this command was canceled by blocking side of VM */
pthread_t
thread
;
/* ID of the thread processing this entry */
}
iojob
;
}
iojob
;
/* Structure to hold list iteration abstraction. */
/* Structure to hold list iteration abstraction. */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment